从https://github.com/vdenotaris/spring-boot-security-saml-sample改编-谢谢@vdenotaris!以及@VladimírSchäfer的示例项目/文档。
SAML仅用于身份验证,而授权则通过rdbms查询处理。
当我遵循Support SAML SSO and normal login问题的早期答案时,表单登录有效并且由IdP发起的SSO即将出现。
问题是,我不太想办法将SAML响应信息传递给DaoAuthenticationProvider
来成功处理retrieveUser
方法。
有人可以查看我的WebSecurityConfigurerAdapter
配置/实现中是否缺少零件/过滤器?
任何帮助一如既往。 谢谢
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.authenticationEntryPoint(samlEntryPoint());
http
.csrf().disable()
.addFilterAfter(new CustomLogFilter(), SecurityContextPersistenceFilter.class)
.authorizeRequests()
.antMatchers("/mappings").permitAll()
.antMatchers("/resource/**").permitAll()
.antMatchers("/usersetting/**").permitAll()
.antMatchers("/security/permissions/**").permitAll()
.antMatchers("/security/canAccess/**").permitAll()
.antMatchers("/login/v1").permitAll()
.antMatchers("/healthcheck").permitAll()
.antMatchers("/saml/**").permitAll()
.antMatchers("/importer/**", "/stomp_publisher/**", "/publish/**").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(new Http403ForbiddenEntryPoint())
.and()
.formLogin()
.loginProcessingUrl("/login/v1")
.usernameParameter("username")
.passwordParameter("password")
.successHandler(authenticationSuccessHandler)
.failureHandler(authenticationFailureHandler)
.and()
.logout()
.logoutUrl("/logout")
.deleteCookies("JSESSIONID")
.logoutSuccessUrl("/login/v1");
http
.addFilterBefore(metadataGeneratorFilter(), ChannelProcessingFilter.class)
.addFilterAfter(samlFilter(), BasicAuthenticationFilter.class);
}
对应的bean:
@Bean
public DaoAuthenticationProvider authProvider() {
DaoAuthenticationProvider authProvider = new CustomDaoAuthenticationProvider();
authProvider.setUserDetailsService(serverUserDetailsService);
authProvider.setPasswordEncoder(encoder());
return authProvider;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(serverUserDetailsService);
auth.authenticationProvider(authProvider());
}
@Bean
public SAMLAuthenticationProvider samlAuthenticationProvider() {
SAMLAuthenticationProvider samlAuthenticationProvider = new SAMLAuthenticationProvider();
samlAuthenticationProvider.setUserDetails(samlUserDetailsServiceImpl);
samlAuthenticationProvider.setForcePrincipalAsString(false);
return samlAuthenticationProvider;
}
@Bean
public SAMLContextProviderImpl contextProvider() {
return new SAMLContextProviderImpl();
}
@Bean
public static SAMLBootstrap sAMLBootstrap() {
return new SAMLBootstrap();
}
@Bean
public WebSSOProfileConsumer webSSOprofileConsumer() {
return new WebSSOProfileConsumerImpl();
}
@Bean
public WebSSOProfile webSSOprofile() {
return new WebSSOProfileImpl();
}
@Bean
public SingleLogoutProfile logoutprofile() {
return new SingleLogoutProfileImpl();
}
@Bean
public WebSSOProfileOptions defaultWebSSOProfileOptions() {
WebSSOProfileOptions webSSOProfileOptions = new WebSSOProfileOptions();
webSSOProfileOptions.setIncludeScoping(false);
return webSSOProfileOptions;
}
@Bean
public SAMLEntryPoint samlEntryPoint() {
SAMLEntryPoint samlEntryPoint = new SAMLEntryPoint();
samlEntryPoint.setDefaultProfileOptions(defaultWebSSOProfileOptions());
return samlEntryPoint;
}
@Bean
public ExtendedMetadata extendedMetadata() {
ExtendedMetadata extendedMetadata = new ExtendedMetadata();
extendedMetadata.setIdpDiscoveryEnabled(true);
extendedMetadata.setSignMetadata(false);
extendedMetadata.setEcpEnabled(true);
return extendedMetadata;
}
@Bean
public SavedRequestAwareAuthenticationSuccessHandler successRedirectHandler() {
SavedRequestAwareAuthenticationSuccessHandler successRedirectHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successRedirectHandler.setDefaultTargetUrl("/login/v1");
return successRedirectHandler;
}
@Bean
public SimpleUrlAuthenticationFailureHandler authenticationFailureHandler() {
SimpleUrlAuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler();
failureHandler.setUseForward(true);
failureHandler.setDefaultFailureUrl("/error");
return failureHandler;
}
@Bean
public SAMLProcessingFilter samlWebSSOProcessingFilter() throws Exception {
SAMLProcessingFilter samlWebSSOProcessingFilter = new SAMLProcessingFilter();
samlWebSSOProcessingFilter.setAuthenticationManager(authenticationManager());
samlWebSSOProcessingFilter.setAuthenticationSuccessHandler(successRedirectHandler());
samlWebSSOProcessingFilter.setAuthenticationFailureHandler(authenticationFailureHandler());
return samlWebSSOProcessingFilter;
}
@Bean
public MetadataGeneratorFilter metadataGeneratorFilter() {
return new MetadataGeneratorFilter(metadataGenerator());
}
@Bean
public HTTPPostBinding httpPostBinding() {
return new HTTPPostBinding(parserPool(), velocityEngine());
}
@Bean
public SAMLProcessorImpl processor() {
Collection<SAMLBinding> bindings = new ArrayList<SAMLBinding>();
bindings.add(httpRedirectDeflateBinding());
bindings.add(httpPostBinding());
bindings.add(artifactBinding(parserPool(), velocityEngine()));
bindings.add(httpSOAP11Binding());
bindings.add(httpPAOS11Binding());
return new SAMLProcessorImpl(bindings);
}
@Bean
public FilterChainProxy samlFilter() throws Exception {
List<SecurityFilterChain> chains = new ArrayList<SecurityFilterChain>();
chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/login/**"),
samlEntryPoint()));
chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/logout/**"),
samlLogoutFilter()));
chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/metadata/**"),
metadataDisplayFilter()));
chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/SSO/**"),
samlWebSSOProcessingFilter()));
chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/SingleLogout/**"),
samlLogoutProcessingFilter()));
return new FilterChainProxy(chains);
}