2016-07-31 31 views
2

我正在尝试使用Grails 3.10和spring-security-core插件创建一个网站。 我对此很新颖。我生成我的所有域类,然后运行该应用程序。 它指引我登录页面。这实际上是一件好事,但现在如何才能解决这个问题,并能看到我的其他控制者和观点。我读了一些博客。我想写一些代码,如请求地图直接访问Grails登录页面

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' 
    } 
    } 

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

+0

告诉我:什么是浏览器中显示当您打开'HTTP://本地主机:8080/secureAnnotated/adminEither':当您打开'HTTP://本地主机:8080/secureAnnotated /任何人' –

+0

指示我再次登录页面 –

+0

两个?或仅用于第一个URL –

回答

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' 
    } 
    } 

由于伯特指出,你正在使用旧的控制器方法和旧的安全进口

除此之外:

看看在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 /人,如果你有,在现有的默认之中值,那么它应该工作。

您也可以不用更新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目录/春/ 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 /常规/ 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 
    } 
} 

对于所有那些很酷的东西来说,你需要将它添加到你的构建中。gradle这个

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

享受

+0

我注释掉//SessionListener.userLoggedIn,因为它没有包括在内。这只是保持一个列表,如果会议登录。如果你卡住给我留言。 – Vahid

+0

谢谢你的回答,帮助我 –

0

对于Spring Security的使用Grails的更高版本,则需要添加以下的conf的文件:

Config.groovy中:

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

相反的: