Grails Spring Security - 手动强制交互式登录

时间:2014-09-03 20:21:02

标签: spring authentication grails spring-security

在我的一个Grails控制器中,我有一个注释为:

的动作
@Secured('permitAll()')

但是,在实际的操作方法中,它会进行多次检查以查看是否真正允许匿名访问(有时它是,有时不是,取决于传递给操作的参数)。从逻辑上讲,将此作为一个操作(而不是具有不同访问级别的多个操作)是有意义的。所以我想知道是否有办法手动触发Spring Security来登录用户。我可以简单地将它们转发到登录页面,但是在登录后不会将它们转发到原始操作。任何想法?

2 个答案:

答案 0 :(得分:0)

以下是我从各种来源汇总的内容。

在您的控制器类中:

...
def authenticationEntryPoint
def authenticationTrustResolver
def springSecurityService
...

private boolean isFullyAuthenticated() {
    def authentication = springSecurityService.authentication
    !authenticationTrustResolver.isAnonymous(authentication) && !authenticationTrustResolver.isRememberMe(authentication)
}

def storeLocation(request) {
    def savedRequest = new DefaultSavedRequest(request,new org.springframework.security.web.PortResolverImpl())

    try {
        Field f = DefaultSavedRequest.getDeclaredField('requestURI')
        f.accessible = true
        f.set savedRequest, request.getForwardURI()
    }
    catch (ex) {
        log.error('Error saving current request location.', ex)
    }

    request.session.setAttribute(WebAttributes.SAVED_REQUEST, savedRequest)
}

def yourView(){
    // Unprotected block
    ...

    // Start of protected block

    if (!isFullyAuthenticated()) {
        new HttpSessionRequestCache().saveRequest(request, response)
        storeLocation(request)
        authenticationEntryPoint.commence(request, response,
                new InsufficientAuthenticationException('You must be authenticated in order to view this page.'))
        return null
    }

    // Protected block
    ...
}

答案 1 :(得分:0)

我遇到了同样的情况,我进入了这个帖子。虽然我认为Chris解决方案可能有效,但我的控制器代码会变得不那么可读。所以,这里有一个更简单的解决方案:

我创建了另一个需要身份验证的操作,并添加了一个代码以重定向到匿名代码。

因此,当您的anon操作中的逻辑达到应该具有auth数据的点时,只需重定向到您的受限操作即可。您只需检查用户,这将与Chris建议的相同。

def springSecurityService

@Secured(['ROLE_MANAGER'])
def login(){
    redirect action: "list"
}

@Secured('permitAll()')
def list(){
    if (params.queryType == "confidential" && springSecurityService.isLoggedIn())
        redirect action: "login"
    ...
}