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

Posted

技术标签:

【中文标题】如何为每个 url 配置 grails/spring 身份验证方案?【英文标题】:How to configure grails/spring authentication scheme per url? 【发布时间】:2011-10-27 06:19:22 【问题描述】:

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

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

谢谢!

【问题讨论】:

【参考方案1】:

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

grails.plugins.springsecurity.useBasicAuth = true

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

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

请注意,以上 URL /api/ 的所有内容都将使用基本身份验证,但 /api/ 以外的所有内容都使用正常的身份验证登录表单!

编辑

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

【讨论】:

另外,小心不要被这个错误所困扰,以免你浪费时间试图弄清楚为什么这对你不起作用:jira.grails.org/browse/GPSPRINGSECURITYCORE-210【参考方案2】:

我遇到了同样的问题,但没有找到好的解决方案。我真的很期待一个干净的解决方案(在上下文中,比如多租户)。

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

我不知道,您的第二个系统是否负担得起这种解决方法。

【讨论】:

【参考方案3】:

您应该进行无状态基本身份验证。为此,请在您的代码中进行以下更改。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)
     

【讨论】:

以上是关于如何为每个 url 配置 grails/spring 身份验证方案?的主要内容,如果未能解决你的问题,请参考以下文章

如何为每个 url 使用 Polly 和 IHttpClientFactory

我将如何为每个主题创建 URL 模式?

如何为每个帖子自动制作带有新 URL 的子页面 [NodeJS]

如何为 ejabberd 配置搜索服务 url?

在 HTMX 中,如何为选择表单元素中的每个选项请求特定的 URL?

如何为Servlet类配置url以及form表单动作元素的写法。