如何为每个URL配置grails / spring身份验证方案?

时间:2011-08-15 12:48:25

标签: spring authentication rest grails

如何使用Spring安全性配置grails应用程序,以便一组url将未经身份验证的用户重定向到http响应代码为200的自定义登录表单,而另一组url是实现restful Web服务并且必须为未经身份验证的客户端返回401 /未授权的响应,以便客户端应用程序可以使用用户名和密码重新发送请求以响应401.

我当前的配置可以使用自定义登录表单处理第一种情况。但是,我需要为restful接口url配置其他类型的身份验证,同时保留人机接口的当前行为。

谢谢!

3 个答案:

答案 0 :(得分:8)

如果我理解你想要做什么,我之前遇到了同样的问题!但使用Spring Security grails Plugin很容易解决它!因此,首先,您必须将应用程序设置为使用基本身份验证:

grails.plugins.springsecurity.useBasicAuth = true

所以你的宁静服务会尝试登录,如果它不起作用,它会转到401! 这很简单,但您还需要使用自定义表单才能正确登录?!因此,您可以配置一些URL以进入正常的登录策略,如下所示:

grails.plugins.springsecurity.filterChain.chainMap = [
    '/api/**': 'JOINED_FILTERS,-exceptionTranslationFilter',
    '/**': 'JOINED_FILTERS,-basicAuthenticationFilter,-basicExceptionTranslationFilter'
 ]

所以注意到,在上面,来到URL / api /的所有东西都将使用Basic Auth,但是任何不是来自/ api /的东西都使用普通的身份验证登录表单!

修改

更多信息请转到http://burtbeckwith.github.com/grails-spring-security-core/docs/manual/guide/16%20Filters.html

答案 1 :(得分:0)

我有同样的问题,并没有找到一个很好的解决方案。我真的很期待一个干净的解决方案(像多租户这样的上下文)。

我最终手动验证了第二个系统的状态和登录部分,它不应该重定向到登录页面(因此我没有使用“安全”注释)。我使用springSecurityService.reauthenticate()(用于手动登录),springSecurityService.isLoggedIn()并在第二个系统的每个控制器中手动执行此操作。如果他不是,我一直在重定向到特定页面。

我不知道,这种解决方案是否适用于您的第二个系统。

答案 2 :(得分:0)

您应该进行无状态基本身份验证。为此,请在您的代码中进行以下更改 的 UrlMappings.groovy

"/api/restLogin"(controller: 'api', action: 'restLogin', parseRequest: true)

Config.groovy

grails.plugin.springsecurity.useBasicAuth = true
grails.plugin.springsecurity.basic.realmName = "Login to My Site"
    grails.plugin.springsecurity.filterChain.chainMap = [
                '*'         : 'statelessSecurityContextPersistenceFilter,logoutFilter,authenticationProcessingFilter,customBasicAuthenticationFilter,securityContextHolderAwareRequestFilter,rememberMeAuthenticationFilter,anonymousAuthenticationFilter,basicExceptionTranslationFilter,filterInvocationInterceptor',
                '/api/': 'JOINED_FILTERS,-basicAuthenticationFilter,-basicExceptionTranslationFilter'
        ]

<强> resources.groovy

statelessSecurityContextRepository(NullSecurityContextRepository) {}

    statelessSecurityContextPersistenceFilter(SecurityContextPersistenceFilter, ref('statelessSecurityContextRepository')) {
    }
    customBasicAuthenticationEntryPoint(CustomBasicAuthenticationEntryPoint) {
        realmName = SpringSecurityUtils.securityConfig.basic.realmName 
    }

    customBasicAuthenticationFilter(BasicAuthenticationFilter, ref('authenticationManager'), ref('customBasicAuthenticationEntryPoint')) {
        authenticationDetailsSource = ref('authenticationDetailsSource')
        rememberMeServices = ref('rememberMeServices')
        credentialsCharset = SpringSecurityUtils.securityConfig.basic.credentialsCharset // 'UTF-8'
    }

    basicAccessDeniedHandler(AccessDeniedHandlerImpl)

    basicRequestCache(NullRequestCache)

    basicExceptionTranslationFilter(ExceptionTranslationFilter, ref('customBasicAuthenticationEntryPoint'), ref('basicRequestCache')) {
        accessDeniedHandler = ref('basicAccessDeniedHandler')
        authenticationTrustResolver = ref('authenticationTrustResolver')
        throwableAnalyzer = ref('throwableAnalyzer')
    }

<强> CustomBasicAuthenticationEntryPoint.groovy

public class CustomBasicAuthenticationEntryPoint extends
        BasicAuthenticationEntryPoint {   

    @Override
    public void commence(HttpServletRequest request,
                         HttpServletResponse response, AuthenticationException authException)
            throws IOException, ServletException {            
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
    }

}

<强> ApiController

@Secured('permitAll')
class ApiController {
def springSecurityService
@Secured("ROLE_USER")
    def restLogin() {        
        User currentUser = springSecurityService.currentUser
        println(currentUser.username)
     }
}