请求地图指导我到Grails的登录页面

时间:2016-07-31 20:20:28

标签: grails spring-security

我正在尝试使用Grails 3.10和spring-security-core插件创建一个网站。 我是如此新鲜。我创建了我的所有域类,然后运行应用程序。 它指示我登录页面。实际上这是一件好事,但现在如何才能通过这个,并可以看到我的其他控制者和观点。我读了一些博客。我想写一些像

这样的代码
import org.codehaus.groovy.grails.plugins.springsecurity.Secured
class SecureAnnotatedController {

  @Secured(['ROLE_ADMIN'])
  def index = {
    render 'you have ROLE_ADMIN'
   }

  @Secured(['ROLE_ADMIN', 'ROLE_ADMIN2'])
  def adminEither = {
     render 'you have ROLE_ADMIN or ROLE_ADMIN2'
   }

   def anybody = {
     render 'anyone can see this'
    }
  }

但我无法理解。谢谢你的帮助。

2 个答案:

答案 0 :(得分:0)

对于带有Grails的Spring Security的更高版本,您需要将以下内容添加到Conf的文件中:

Config.groovy:

grails.plugin.springsecurity.successHandler.alwaysUseDefault = true
grails.plugin.springsecurity.successHandler.defaultTargetUrl = '/your-url'

而不是:

答案 1 :(得分:0)

import grails.plugin.springsecurity.annotation.Secured
class SecureAnnotatedController {

  @Secured(['ROLE_ADMIN'])
  def index() {
    render text: 'you have ROLE_ADMIN'
   }

  @Secured(['ROLE_ADMIN', 'ROLE_ADMIN2'])
  def adminEither() { 
     render text: 'you have ROLE_ADMIN or ROLE_ADMIN2'
   }

   def anybody () { 
     render text: 'anyone can see this'
    }
  }

正如Burt指出的那样,你正在使用旧的控制器方法和旧的安全导入

超越这个:

看一下grails-app / conf / application.groov:

grails.plugin.springsecurity.controllerAnnotations.staticRules = [
        [pattern: '/',               access: ['permitAll']],
        [pattern: '/error',          access: ['permitAll']],
        [pattern: '/SecureAnnotatedController/anybody',          access: ['permitAll']],
        [pattern: '/index/**',          access: ['permitAll']],

在上面我直接添加了/ SecureAnnotatedController / anybody,如果你在现有的默认值中有它,那么它应该可以工作。

您也可以在方法上方更新applucation.groovy使用@Secured(['permitAll'])

上面的

应该让你需要的工作。以下是更高级的,包括锁定失败的尝试 这是一个很棒的插件,需要时间来吸收其细节。

关于以上帖子:

//grails.plugin.springsecurity.successHandler.defaultTargetUrl = "/helloAgain/${System.currentTimeMillis()}"
//grails.plugins.springsecurity.useSecurityEventListener = true

grails.plugin.springsecurity.successHandler.alwaysUseDefault = true
grails.plugin.springsecurity.useRoleGroups = true


brutforce {
    loginAttempts {
        time = 5
        allowedNumberOfAttempts = 3
    }
}

我最初让它去了helloAgain,它进行了重定向但是在这一点上是一种注册传入用户的hackish方式。现在我正在使用

grails.plugin.springsecurity.useSecurityEventListener = true

然后将其输入grails-app / conf / spring / resources.groovy

import myapp.utils.CustomSecurityEventListener
import myapp.utils.CustomSecurityFailureEventListener
import myapp.utils.RedirectFailureToRegistration
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler

// Place your Spring DSL code here
beans = {
    redirectFailureHandlerExample(SimpleUrlAuthenticationFailureHandler) {
        defaultFailureUrl = '/failed'
    }

    redirectFailureHandler(RedirectFailureToRegistration) {
        defaultFailureUrl = '/failed'
        registrationUrl = '/'
    }
    /*
    multipartResolver(ContentLengthAwareCommonsMultipartResolver) {
        defaultEncoding = 'UTF-8'
    }
    */
    customerSecurityEventListener(CustomSecurityEventListener)
    customSecurityFailureEventListener(CustomSecurityFailureEventListener)

现在这些文件:在我的src / main / groovy / myapp / utils中我有

package myapp.utils

import grails.util.Holders
import org.springframework.context.ApplicationListener
import org.springframework.security.authentication.event.AuthenticationSuccessEvent
import org.springframework.security.core.userdetails.UserDetails

class CustomSecurityEventListener implements ApplicationListener<AuthenticationSuccessEvent> {
    //private static Collection activeUsers = Collections.synchronizedList(new ArrayList())
    def loginAttemptCacheService = Holders.grailsApplication.mainContext.getBean('loginAttemptCacheService')

    void onApplicationEvent(AuthenticationSuccessEvent event) {
        def userDetails = (UserDetails) event.getAuthentication().getPrincipal()
        if (userDetails) {
            //SessionListener.userLoggedIn(userDetails.getUsername())
            loginAttemptCacheService.loginSuccess(event.authentication.name)
        }
    }
    // public static Collection getActiveUsers() {
    //     return Collections.unmodifiableList(activeUsers)
    //  }

}


package myapp.utils

import myapp.users.LoginAttemptCacheService
import grails.util.Holders
import org.springframework.context.ApplicationListener
import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent

class CustomSecurityFailureEventListener implements ApplicationListener<AuthenticationFailureBadCredentialsEvent> {

    def loginAttemptCacheService = Holders.grailsApplication.mainContext.getBean('loginAttemptCacheService')

    void onApplicationEvent(AuthenticationFailureBadCredentialsEvent event) {
        String username = (String) event.getAuthentication().getPrincipal()
        if (username) {
            loginAttemptCacheService.failLogin(event.authentication.name)
        }
    }

}

服务:

import com.google.common.cache.CacheBuilder
import com.google.common.cache.CacheLoader
import com.google.common.cache.LoadingCache
import grails.core.GrailsApplication
import grails.core.support.GrailsApplicationAware
import grails.transaction.Transactional

import java.util.concurrent.TimeUnit
import org.apache.commons.lang.math.NumberUtils
import javax.annotation.PostConstruct

class LoginAttemptCacheService implements GrailsApplicationAware {
    def config
    GrailsApplication grailsApplication
    private LoadingCache attempts
    private int allowedNumberOfAttempts


    @PostConstruct
    void init() {
        allowedNumberOfAttempts = config.brutforce.loginAttempts.allowedNumberOfAttempts
        int time = config.brutforce.loginAttempts.time
        log.info "account block configured for $time minutes"
        attempts = CacheBuilder.newBuilder()
                .expireAfterWrite(time, TimeUnit.MINUTES)
                .build({0} as CacheLoader);
    }

    /**
     * Triggers on each unsuccessful login attempt and increases number of attempts in local accumulator
     * @param login - username which is trying to login
     * @return
     */
    def failLogin(String login) {
        def numberOfAttempts = attempts.get(login)
        log.debug "fail login $login previous number for attempts $numberOfAttempts"
        numberOfAttempts++
        if (numberOfAttempts > allowedNumberOfAttempts) {
            blockUser(login)
            attempts.invalidate(login)
        } else {
            attempts.put(login, numberOfAttempts)
        }
    }

    /**
     * Triggers on each successful login attempt and resets number of attempts in local accumulator
     * @param login - username which is login
     */
    def loginSuccess(String login) {
        log.debug "successfull login for $login"
        attempts.invalidate(login)
    }

    /**
     * Disable user account so it would not able to login
     * @param login - username that has to be disabled
     */
    @Transactional
    private void blockUser(String login) {
        log.debug "blocking user: $login"
            def user = User.findByUsername(login)
            if (user) {
                user.accountLocked = true
                user.save(flush: true)
            }
    }

    void setGrailsApplication(GrailsApplication ga) {
        config = ga.config
    }
}

对于所有那些很酷的东西,你需要将它添加到你的build.gradle

//caching user failure attempts //CustomerSecurityFailureEventListener.groovy
    compile 'com.google.guava:guava:11.0.1'

享受