grails
为了加强我们新Grails应用程序中的安全性,我着手实现了Spring Security Plugin 。
使用标准的用户名/密码进行安装和运行非常简单,因为所有这些都由插件自动连接。
这解决了我一半的问题,但是我们还需要支持SAML身份验证,并且没有明确的示例来说明如何实现。
如果有人有类似的要求,我想分享一下我的作品。
我将不专注于SAML细节,而是关注如何在grails中构建任何自定义身份验证提供程序。
您可以通过扩展AbstractAuthenticationProcessingFilter并将其注册到Spring来将URL映射到过滤器。
然后,您可以提供该URL进行自定义身份验证。
就我而言,它看起来像这样:
class SamlAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public SamlAuthenticationFilter() {
super("/somecustomauth")
}
@Override
Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) {
if (!request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod())
}
String accessToken = request.getParameter("sometoken")
return this.getAuthenticationManager().authenticate(new SamlAuthenticationToken(accessToken));
}
}
然后将过滤器与身份验证提供程序一起设置为Spring Bean,稍后将讨论该身份验证提供程序:
import SamlAuthenticationFilter
import SamlAuthenticationProvider
beans = {
samlAuthenticationFilter(SamlAuthenticationFilter) {
authenticationManager = ref('authenticationManager')
sessionAuthenticationStrategy = ref('sessionAuthenticationStrategy')
authenticationSuccessHandler = ref('authenticationSuccessHandler')
authenticationFailureHandler = ref('authenticationFailureHandler')
rememberMeServices = ref('rememberMeServices')
authenticationDetailsSource = ref('authenticationDetailsSource')
}
samlAuthenticationProvider(SamlAuthenticationProvider) {
sAMLAuthenticationService = ref('SAMLAuthenticationService')
sAMLSettingsService = ref('SAMLSettingsService')
userDetailsService = ref('userDetailsService')
passwordEncoder = ref('passwordEncoder')
userCache = ref('userCache')
saltSource = ref('saltSource')
preAuthenticationChecks = ref('preAuthenticationChecks')
postAuthenticationChecks = ref('postAuthenticationChecks')
}
}
然后,bean在Bootstrap中注册为过滤器:
import org.codehaus.groovy.grails.plugins.springsecurity.SecurityFilterPosition
import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
class BootStrap {
def init = { servletContext ->
SpringSecurityUtils.clientRegisterFilter('samlAuthenticationFilter', SecurityFilterPosition.SECURITY_CONTEXT_FILTER.order + 10)
}
def destroy = {
}
}
我们还需要创建由过滤器和身份验证提供程序使用的令牌类:
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.core.userdetails.UserDetails
class SamlAuthenticationToken extends UsernamePasswordAuthenticationToken {
String token
public SamlAuthenticationToken(String token) {
super(null, null);
this.token = token;
}
public SamlAuthenticationToken(UserDetails principal, String samlResponse) {
super(principal, samlResponse, principal.getAuthorities())
}
}
最后是AuthenticationProvider本身:
import org.springframework.security.authentication.dao.DaoAuthenticationProvider
import org.springframework.security.core.Authentication
import sonicg.authentication.SAMLAuthenticationService
class SamlAuthenticationProvider extends DaoAuthenticationProvider {
@Override
Authentication authenticate(Authentication authentication) {
def token = (SamlAuthenticationToken) authentication
def user = // define user if credentials check out
if (user){
def userDetails = userDetailsService.loadUserByUsername(user.username)
def token1 = new SamlAuthenticationToken(userDetails, token.samlResponse)
return token1
}else{
return null
}
}
@Override
public boolean supports(Class authentication) {
return (SamlAuthenticationToken.class.isAssignableFrom(authentication));
}
}
最后一个难题是告诉Spring在Config.groovy中的其他三个标准之前尝试使用此身份验证提供程序:
grails.plugins.springsecurity.providerNames = [
'samlAuthenticationProvider',
'daoAuthenticationProvider',
'anonymousAuthenticationProvider',
'rememberMeAuthenticationProvider']
在这种情况下,自定义过滤器优先是很重要的,因为它的Token是UsernamePasswordAuthenticationToken的子类。
如果DAO提供者是第一个,它将在我们的过滤器获得机会之前尝试对自定义令牌进行身份验证。
而已!
希望这对某人有用。
这也只是初稿,也许一旦安全要求发展起来,我就可以完善实现并分享学到的知识。
参考:来自我们的JCG合作伙伴 Kali Kallin的Grails自定义AuthenticationProvider在Kallin Nagelberg进入西方博客的过程中。
翻译自: https://www.javacodegeeks.com/2012/07/grails-custom-authenticationprovider.html
grails