Grails,spring 安全 - 登录控制器的导入不工作
Grails, spring security - login controller's imports not working
我在 intellij 中启动了一个新的 Grails (2.4.4) 项目并添加了 compile ":spring-security-core:2.0.0"
以安装 spring 安全性 - 这工作正常。然后我 运行 s2-quickstart io.mylife.feedmyface User Role
生成域 类 用户、角色和用户角色 - 这也很好用,我什至成功地引导了几个角色和用户。接下来,我分别从 target/work/plugins/spring-security-core-2.0.0/grails-app/controllers/grails/plugin/springsecurity
和 target/work/plugins/spring-security-core-2.0.0/grails-app/views/login
复制了登录和注销控制器以及登录视图。这就是问题所在。许多导入以及其他关键字都被 intellij 标记为红色,例如弹出窗口 cannot resolve symbol 'Secured'
。在视图中我得到了几个类似的错误,例如<div class='errors'><g:message code="springSecurity.denied.message" /></div>
,springSecurity.denied.message
将被标记为红色,弹出窗口 cannot resolve property key
。我不太担心这些观点,因为我过去注意到生成的代码有时会这样做而不会造成任何真正的麻烦。我只想了解如何修复控制器。只是为了说明我的基础,我会提到我正在使用 Postgresql 数据库,但我怀疑这会有所作为吗?如果我需要提供更多信息,请告诉我。这是控制器的代码:
登录控制器:
/* Copyright 2013-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.mylife.feedmyface
import grails.converters.JSON
import javax.servlet.http.HttpServletResponse
/* 'security is red on all of the below imports'*/
import org.springframework.security.access.annotation.Secured
import org.springframework.security.authentication.AccountExpiredException
import org.springframework.security.authentication.CredentialsExpiredException
import org.springframework.security.authentication.DisabledException
import org.springframework.security.authentication.LockedException
import org.springframework.security.core.context.SecurityContextHolder as SCH
import org.springframework.security.web.WebAttributes
@Secured('permitAll') // 'Secured' is red
class LoginController {
/**
* Dependency injection for the authenticationTrustResolver.
*/
def authenticationTrustResolver
/**
* Dependency injection for the springSecurityService.
*/
def springSecurityService
/**
* Default action; redirects to 'defaultTargetUrl' if logged in, /login/auth otherwise.
*/
def index() {
if (springSecurityService.isLoggedIn()) {
redirect uri: SpringSecurityUtils.securityConfig.successHandler.defaultTargetUrl
}
else {
redirect action: 'auth', params: params
}
}
/**
* Show the login page.
*/
def auth() {
def config = SpringSecurityUtils.securityConfig
if (springSecurityService.isLoggedIn()) {
redirect uri: config.successHandler.defaultTargetUrl
return
}
String view = 'auth'
String postUrl = "${request.contextPath}${config.apf.filterProcessesUrl}"
render view: view, model: [postUrl: postUrl,
rememberMeParameter: config.rememberMe.parameter]
}
/**
* The redirect action for Ajax requests.
*/
def authAjax() {
response.setHeader 'Location', SpringSecurityUtils.securityConfig.auth.ajaxLoginFormUrl
response.sendError HttpServletResponse.SC_UNAUTHORIZED
}
/**
* Show denied page.
*/
def denied() {
if (springSecurityService.isLoggedIn() &&
authenticationTrustResolver.isRememberMe(SCH.context?.authentication)) {
// have cookie but the page is guarded with IS_AUTHENTICATED_FULLY
redirect action: 'full', params: params
}
}
/**
* Login page for users with a remember-me cookie but accessing a IS_AUTHENTICATED_FULLY page.
*/
def full() {
def config = SpringSecurityUtils.securityConfig
render view: 'auth', params: params,
model: [hasCookie: authenticationTrustResolver.isRememberMe(SCH.context?.authentication),
postUrl: "${request.contextPath}${config.apf.filterProcessesUrl}"]
}
/**
* Callback after a failed login. Redirects to the auth page with a warning message.
*/
def authfail() {
String msg = ''
def exception = session[WebAttributes.AUTHENTICATION_EXCEPTION]
if (exception) {
if (exception instanceof AccountExpiredException) { // 'AccountExpiredException' is red
msg = g.message(code: "springSecurity.errors.login.expired")
}
else if (exception instanceof CredentialsExpiredException) { // 'CredentialsExpiredException' is red
msg = g.message(code: "springSecurity.errors.login.passwordExpired")
}
else if (exception instanceof DisabledException) { // 'DisabledException' is red
msg = g.message(code: "springSecurity.errors.login.disabled")
}
else if (exception instanceof LockedException) { // 'LockedException' is red
msg = g.message(code: "springSecurity.errors.login.locked")
}
else {
msg = g.message(code: "springSecurity.errors.login.fail")
}
}
if (springSecurityService.isAjax(request)) {
render([error: msg] as JSON)
}
else {
flash.message = msg
redirect action: 'auth', params: params
}
}
/**
* The Ajax success redirect url.
*/
def ajaxSuccess() {
render([success: true, username: springSecurityService.authentication.name] as JSON)
}
/**
* The Ajax denied redirect url.
*/
def ajaxDenied() {
render([error: 'access denied'] as JSON)
}
}
注销控制器:
/* Copyright 2013-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.mylife.feedmyface
import javax.servlet.http.HttpServletResponse
/* Again, 'security' is red */
import org.springframework.security.access.annotation.Secured
import org.springframework.security.web.RedirectStrategy
@Secured('permitAll') // 'Secured' is red
class LogoutController {
/** Dependency injection for RedirectStrategy. */
RedirectStrategy redirectStrategy // 'RedirectStrategy' is red
/**
* Index action. Redirects to the Spring security logout uri.
*/
def index() {
if (!request.post && SpringSecurityUtils.getSecurityConfig().logout.postOnly) {
response.sendError HttpServletResponse.SC_METHOD_NOT_ALLOWED // 405
return
}
// TODO put any pre-logout code here
redirectStrategy.sendRedirect request, response, SpringSecurityUtils.securityConfig.logout.filterProcessesUrl // '/j_spring_security_logout'
response.flushBuffer()
}
}
没有必要复制登录和注销控制器。在 bootstrap.groovy 中创建示例用户和角色后,您只需使用 @secure 注释或 config.groovy 中的请求映射配置自定义控制器的权限。有关更多信息,您可以在插件文档中遵循此 tutorial。
我在 intellij 中启动了一个新的 Grails (2.4.4) 项目并添加了 compile ":spring-security-core:2.0.0"
以安装 spring 安全性 - 这工作正常。然后我 运行 s2-quickstart io.mylife.feedmyface User Role
生成域 类 用户、角色和用户角色 - 这也很好用,我什至成功地引导了几个角色和用户。接下来,我分别从 target/work/plugins/spring-security-core-2.0.0/grails-app/controllers/grails/plugin/springsecurity
和 target/work/plugins/spring-security-core-2.0.0/grails-app/views/login
复制了登录和注销控制器以及登录视图。这就是问题所在。许多导入以及其他关键字都被 intellij 标记为红色,例如弹出窗口 cannot resolve symbol 'Secured'
。在视图中我得到了几个类似的错误,例如<div class='errors'><g:message code="springSecurity.denied.message" /></div>
,springSecurity.denied.message
将被标记为红色,弹出窗口 cannot resolve property key
。我不太担心这些观点,因为我过去注意到生成的代码有时会这样做而不会造成任何真正的麻烦。我只想了解如何修复控制器。只是为了说明我的基础,我会提到我正在使用 Postgresql 数据库,但我怀疑这会有所作为吗?如果我需要提供更多信息,请告诉我。这是控制器的代码:
登录控制器:
/* Copyright 2013-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.mylife.feedmyface
import grails.converters.JSON
import javax.servlet.http.HttpServletResponse
/* 'security is red on all of the below imports'*/
import org.springframework.security.access.annotation.Secured
import org.springframework.security.authentication.AccountExpiredException
import org.springframework.security.authentication.CredentialsExpiredException
import org.springframework.security.authentication.DisabledException
import org.springframework.security.authentication.LockedException
import org.springframework.security.core.context.SecurityContextHolder as SCH
import org.springframework.security.web.WebAttributes
@Secured('permitAll') // 'Secured' is red
class LoginController {
/**
* Dependency injection for the authenticationTrustResolver.
*/
def authenticationTrustResolver
/**
* Dependency injection for the springSecurityService.
*/
def springSecurityService
/**
* Default action; redirects to 'defaultTargetUrl' if logged in, /login/auth otherwise.
*/
def index() {
if (springSecurityService.isLoggedIn()) {
redirect uri: SpringSecurityUtils.securityConfig.successHandler.defaultTargetUrl
}
else {
redirect action: 'auth', params: params
}
}
/**
* Show the login page.
*/
def auth() {
def config = SpringSecurityUtils.securityConfig
if (springSecurityService.isLoggedIn()) {
redirect uri: config.successHandler.defaultTargetUrl
return
}
String view = 'auth'
String postUrl = "${request.contextPath}${config.apf.filterProcessesUrl}"
render view: view, model: [postUrl: postUrl,
rememberMeParameter: config.rememberMe.parameter]
}
/**
* The redirect action for Ajax requests.
*/
def authAjax() {
response.setHeader 'Location', SpringSecurityUtils.securityConfig.auth.ajaxLoginFormUrl
response.sendError HttpServletResponse.SC_UNAUTHORIZED
}
/**
* Show denied page.
*/
def denied() {
if (springSecurityService.isLoggedIn() &&
authenticationTrustResolver.isRememberMe(SCH.context?.authentication)) {
// have cookie but the page is guarded with IS_AUTHENTICATED_FULLY
redirect action: 'full', params: params
}
}
/**
* Login page for users with a remember-me cookie but accessing a IS_AUTHENTICATED_FULLY page.
*/
def full() {
def config = SpringSecurityUtils.securityConfig
render view: 'auth', params: params,
model: [hasCookie: authenticationTrustResolver.isRememberMe(SCH.context?.authentication),
postUrl: "${request.contextPath}${config.apf.filterProcessesUrl}"]
}
/**
* Callback after a failed login. Redirects to the auth page with a warning message.
*/
def authfail() {
String msg = ''
def exception = session[WebAttributes.AUTHENTICATION_EXCEPTION]
if (exception) {
if (exception instanceof AccountExpiredException) { // 'AccountExpiredException' is red
msg = g.message(code: "springSecurity.errors.login.expired")
}
else if (exception instanceof CredentialsExpiredException) { // 'CredentialsExpiredException' is red
msg = g.message(code: "springSecurity.errors.login.passwordExpired")
}
else if (exception instanceof DisabledException) { // 'DisabledException' is red
msg = g.message(code: "springSecurity.errors.login.disabled")
}
else if (exception instanceof LockedException) { // 'LockedException' is red
msg = g.message(code: "springSecurity.errors.login.locked")
}
else {
msg = g.message(code: "springSecurity.errors.login.fail")
}
}
if (springSecurityService.isAjax(request)) {
render([error: msg] as JSON)
}
else {
flash.message = msg
redirect action: 'auth', params: params
}
}
/**
* The Ajax success redirect url.
*/
def ajaxSuccess() {
render([success: true, username: springSecurityService.authentication.name] as JSON)
}
/**
* The Ajax denied redirect url.
*/
def ajaxDenied() {
render([error: 'access denied'] as JSON)
}
}
注销控制器:
/* Copyright 2013-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.mylife.feedmyface
import javax.servlet.http.HttpServletResponse
/* Again, 'security' is red */
import org.springframework.security.access.annotation.Secured
import org.springframework.security.web.RedirectStrategy
@Secured('permitAll') // 'Secured' is red
class LogoutController {
/** Dependency injection for RedirectStrategy. */
RedirectStrategy redirectStrategy // 'RedirectStrategy' is red
/**
* Index action. Redirects to the Spring security logout uri.
*/
def index() {
if (!request.post && SpringSecurityUtils.getSecurityConfig().logout.postOnly) {
response.sendError HttpServletResponse.SC_METHOD_NOT_ALLOWED // 405
return
}
// TODO put any pre-logout code here
redirectStrategy.sendRedirect request, response, SpringSecurityUtils.securityConfig.logout.filterProcessesUrl // '/j_spring_security_logout'
response.flushBuffer()
}
}
没有必要复制登录和注销控制器。在 bootstrap.groovy 中创建示例用户和角色后,您只需使用 @secure 注释或 config.groovy 中的请求映射配置自定义控制器的权限。有关更多信息,您可以在插件文档中遵循此 tutorial。