我有一个Web应用程序,我正在迁移到Grails 3.3.9(来自Grails 2.3.11)。当前版本的应用程序使用Spring Security LDAP进行身份验证(用户在尝试访问站点时会看到登录表单,并输入用户名和密码)。较新版本的应用程序将使用Spring Security SAML插件进行身份验证(通常称为单点登录)。
我有单点登录(SSO)工作,但SSO登录页面只有在用户在我们办公室时才能访问(具有一定的IP地址)。在用户不在我们办公室的情况下(IP地址不在我们的网络中)。我希望用户可以选择使用Spring Security LDAP登录表单进行登录。
我有点失去了怎么做。从我收集的信息中我需要在application.groovy
中定义我的安全提供程序(我使用了默认的Spring Security提供程序,因为它们似乎单独完成了这项工作)。我不明白的是,我如何告诉Grails每个用户使用哪两种登录方法。在我的实例中,它将检查用户的IP地址(我已经有代码),但我怎么说,例如:
if(ipAddress matches internalIPRange) use samlAuthenticationProvider
else{use ldapAuthProvider}
这是在application.groovy
中设置的提供者
grails.plugin.springsecurity.providerNames = ['samlAuthenticationProvider', 'ldapAuthProvider', 'daoAuthenticationProvider', 'anonymousAuthenticationProvider']
此外,我不知道如何手动调用提供程序(如果我不得不猜测,就像provider.invoke()
)。
它似乎很容易实现。
你这样扩展ExceptionTranslationFilter:
class IpAwareExceptionTranslationFilter extends ExceptionTranslationFilter {
AuthenticationEntryPoint ldapAuthenticationEntryPoint
@Override
void sendStartAuthentication(HttpServletRequest request,
HttpServletResponse response, FilterChain chain,
AuthenticationException reason) throws ServletException, IOException {
SecurityContextHolder.context.authentication = null
requestCache.saveRequest request, response
logger.debug 'Calling Authentication entry point.'
if( isAllowedIpAddress( request ) )
authenticationEntryPoint.commence request, response, reason // default SAML
else
ldapAuthenticationEntryPoint.commence request, response, reason // LDAP
}
}
然后在bean
中将过滤器声明为resources.groovy
:
beans = {
exceptionTranslationFilter( IpAwareExceptionTranslationFilter ){
authenticationEntryPoint = new LoginUrlAuthenticationEntryPoint( '/saml/login' )
ldapAuthenticationEntryPoint = new LoginUrlAuthenticationEntryPoint( '/ldap/login' )
}
}
它应该替换过滤器链中的默认exceptionTranslationFilter
。