基于 SAML 断言授权的 SAML2 身份验证
Posted
技术标签:
【中文标题】基于 SAML 断言授权的 SAML2 身份验证【英文标题】:SAML2 Authentication with authorization based on SAML assertions 【发布时间】:2022-01-17 03:21:12 【问题描述】:我正在使用spring-security-saml2-service-provider
针对 SAML IdP 对我的 SpringBoot webapp 进行身份验证 - 这很有效。我还可以使用@AuthenticationPrincipal Saml2AuthenticatedPrincipal principal
访问 REST 控制器中的 SAML 断言,但我想做的是使用 Saml2AuthenticatedPrincipal 主体中的断言中的值限制通过 url 进行的访问 - 这是 SAML 联盟中发布值的常用方法eduPersonEntitlement,并据此决定访问权限。有人做过吗?我对此的所有研究/试验都一无所获。
这是我目前所拥有的:
@EnableWebSecurity
public class SAMLSecurityConfig extends WebSecurityConfigurerAdapter
@Autowired
RelyingPartyRegistrationRepository relyingPartyRegistrationRepository;
protected void configure(HttpSecurity http) throws Exception
RelyingPartyRegistrationResolver relyingPartyRegistrationResolver =
new DefaultRelyingPartyRegistrationResolver(this.relyingPartyRegistrationRepository);
Saml2MetadataFilter filter = new Saml2MetadataFilter(relyingPartyRegistrationResolver, new OpenSamlMetadataResolver());
http
.saml2Login(withDefaults())
.addFilterBefore(filter, Saml2WebSsoAuthenticationFilter.class).antMatcher("/**")
.authorizeRequests()
.anyRequest().authenticated();
我认为我需要将authenticated()
替换为可能与角色有关的东西,并在用户登录时以某种方式为用户设置角色,但对此一无所知。有什么想法吗?
【问题讨论】:
【参考方案1】:好的,开始工作了....您需要自定义 saml2Login - 用新的自定义程序替换 withDefaults() 方法(下面的 Saml2LoginSettings):
SAMLSecurityconfig.java:
@EnableWebSecurity
public class SAMLSecurityConfig extends WebSecurityConfigurerAdapter
@Autowired
RelyingPartyRegistrationRepository relyingPartyRegistrationRepository;
@Autowired
Saml2LoginSettings settings;
protected void configure(HttpSecurity http) throws Exception
RelyingPartyRegistrationResolver relyingPartyRegistrationResolver =
new DefaultRelyingPartyRegistrationResolver(this.relyingPartyRegistrationRepository);
Saml2MetadataFilter filter = new Saml2MetadataFilter(relyingPartyRegistrationResolver, new OpenSamlMetadataResolver());
http
.saml2Login(settings)
.addFilterBefore(filter, Saml2WebSsoAuthenticationFilter.class).antMatcher("/**") //
.authorizeRequests()
.antMatchers("/attributes").hasAuthority("ADMIN")
.anyRequest().authenticated();
使用 Saml2LoginSettings.java:
@Component
class Saml2LoginSettings implements Customizer <Saml2LoginConfigurer<HttpSecurity>>
@Override
public void customize(Saml2LoginConfigurer<HttpSecurity> t)
t.successHandler(new SavedRequestAwareAuthenticationSuccessHandler()
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException
authentication = assignAuthorities (authentication, request);
super.onAuthenticationSuccess(request, response, authentication);
);
分配权限有点麻烦,但这很管用:
private Authentication assignAuthorities (Authentication authentication, HttpServletRequest request)
Collection<SimpleGrantedAuthority> oldAuthorities = (Collection<SimpleGrantedAuthority>)SecurityContextHolder.getContext()
.getAuthentication().getAuthorities();
DefaultSaml2AuthenticatedPrincipal princ = (DefaultSaml2AuthenticatedPrincipal) authentication.getPrincipal();
if (princ.getAttribute("urn:oid:1.3.6.1.4.1.5923.1.1.1.7").contains("urn:mace:dir:entitlement:common-lib-terms"))
List<SimpleGrantedAuthority> updatedAuthorities = new ArrayList<SimpleGrantedAuthority>();
updatedAuthorities.addAll(oldAuthorities);
updatedAuthorities.add(new SimpleGrantedAuthority("ADMIN"));
Saml2Authentication sAuth = (Saml2Authentication) authentication;
sAuth = new Saml2Authentication(
(AuthenticatedPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal(),
sAuth.getSaml2Response(),
updatedAuthorities
);
SecurityContextHolder.getContext().setAuthentication(sAuth);
return sAuth;
else
return authentication;
示例代码here
【讨论】:
以上是关于基于 SAML 断言授权的 SAML2 身份验证的主要内容,如果未能解决你的问题,请参考以下文章
服务提供者之间的 SAML 2.0 身份验证断言(C#、.net、MVC4、组件空间)