Grails 3 Spring Security中如何使用IS_AUTHENTICATED_FULLY认证控制器?
解决Grails 3 + Spring Security中
IS_AUTHENTICATED_FULLY认证与登录重定向问题 我来帮你梳理下Grails 3集成Spring Security时,用IS_AUTHENTICATED_FULLY实现控制器认证并自动重定向登录页的关键步骤和排查点——我之前也踩过不少类似的坑,应该能帮到你:
一、先把基础配置捋扎实
首先得确保Spring Security的核心依赖和配置没出错:
- 检查
build.gradle里的插件依赖,Grails 3对应的Spring Security Core插件版本要匹配,比如Grails 3.3.x可以用3.2.x系列,依赖写法:compile "org.grails.plugins:spring-security-core:3.2.3" - 打开生成的
SecurityConfig(或者叫ApplicationSecurityConfig),确认登录相关的核心配置:// 用户、角色相关的域类配置(根据你的实际包名调整) grails.plugin.springsecurity.userLookup.userDomainClassName = 'com.yourapp.User' grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'com.yourapp.UserRole' grails.plugin.springsecurity.authority.className = 'com.yourapp.Role' // 登录跳转的关键配置,必须确保路径正确 grails.plugin.springsecurity.loginController.auth.loginUrl = '/login/auth' grails.plugin.springsecurity.successHandler.defaultTargetUrl = '/' grails.plugin.springsecurity.failureHandler.defaultFailureUrl = '/login/auth?login_error=1'
二、@Secured注解的正确打开方式
如果你想用注解来控制认证,注意这几个细节:
- 直接在控制器类或者单个方法上添加注解,比如给整个控制器加认证:
import grails.plugin.springsecurity.annotation.Secured @Secured(['IS_AUTHENTICATED_FULLY']) class DashboardController { def index() { // 你的业务逻辑 } } - 要确保注解支持已经开启,在
SecurityConfig里加上:// 单独用注解模式,或者混合Requestmap模式 grails.plugin.springsecurity.securityConfigType = "Annotation" // 混合模式的话就写:"InterceptUrlMap,Annotation" - 划重点:注解的优先级比Requestmap高,如果同时配置了两种方式,注解规则会先生效,别搞混了。
三、Requestmap配置的注意事项(如果用这种方式)
要是你更倾向于用Requestmap来管理URL权限,得注意:
- 先在
SecurityConfig里设置配置类型为Requestmap:grails.plugin.springsecurity.securityConfigType = "Requestmap" - 在
Bootstrap.groovy里初始化权限规则,一定要给登录页放行,不然未登录时跳转登录页会被拦截,直接死循环:import grails.plugin.springsecurity.Requestmap class BootStrap { def init = { servletContext -> // 给受保护的控制器配置IS_AUTHENTICATED_FULLY if (!Requestmap.findByUrl('/dashboard/**')) { new Requestmap( url: '/dashboard/**', configAttribute: 'IS_AUTHENTICATED_FULLY' ).save(flush: true, failOnError: true) } // 必须放行登录相关路径,允许匿名访问 if (!Requestmap.findByUrl('/login/**')) { new Requestmap( url: '/login/**', configAttribute: 'IS_AUTHENTICATED_ANONYMOUSLY' ).save(flush: true, failOnError: true) } // 静态资源也记得放行,比如/css/**、/js/**这些 if (!Requestmap.findByUrl('/assets/**')) { new Requestmap( url: '/assets/**', configAttribute: 'IS_AUTHENTICATED_ANONYMOUSLY' ).save(flush: true, failOnError: true) } } def destroy = { } } - 启动项目后,去数据库里看看
requestmap表,确认数据已经正确保存,URL和权限规则没写错。
四、常见坑的排查方法
要是配置完还是没效果,试试这些排查步骤:
- 未登录时不跳转登录页,反而返回403/401:
- 检查是不是AJAX请求,Spring Security默认对AJAX请求不会重定向,而是返回JSON。如果是普通浏览器请求,确认
grails.plugin.springsecurity.redirectStrategy.redirectUrl没被错误修改。 - 确认
grails.plugin.springsecurity.exceptionTranslationFilter.allowSessionCreation = true(默认是true,改了会影响会话创建,导致重定向出问题)。
- 检查是不是AJAX请求,Spring Security默认对AJAX请求不会重定向,而是返回JSON。如果是普通浏览器请求,确认
- 注解完全不生效:
- 执行
grails clean清理缓存,然后重启项目——Grails有时候缓存会导致配置不生效,这招屡试不爽。 - 检查控制器是不是被Spring正确管理,Grails 3的控制器默认是被管理的,但如果自定义了Bean配置,别把控制器的Bean给丢了。
- 执行
- Requestmap规则不生效:
- 确认
grails.plugin.springsecurity.requestMap.className配置的是你用的Requestmap类(默认是grails.plugin.springsecurity.Requestmap,如果自定义了就写自己的类名)。 - 看看数据库里的Requestmap记录,有没有重复的URL规则,或者URL格式写错(比如少了
**通配符)。
- 确认
五、最后验证一下
启动项目后,直接访问受保护的页面(比如/dashboard):
- 未登录状态下,应该自动跳转到
/login/auth登录页; - 输入正确的账号密码,应该跳转到配置的默认首页或者受保护的页面;
- 输错密码的话,会跳转到带
login_error=1参数的登录页,提示登录失败。
内容的提问来源于stack exchange,提问作者Nikhil Shrestha
相关产品推荐
相关产品推荐

