2016-07-12 19 views
0

Ich versuche zu implementieren tokenbasierte Authentifizierung mit Spring Security Plugin (2.0.0) und Spring Authentication Rest Plugin (1.5.3) in Grails Framework (2.5 .0). Ich setze das Header-Feld "x-auth-token" auf token und poste auf die Ziel-Controller-URL. Allerdings IDE (IntelliJ IDEA) herausspringen diese FehlermeldungGrails, Spring Sicherheitslücke Plugin, kann nicht loadUserByToken() auf Nullobjekt aufrufen

| Error 2016-07-12 15:58:27,864 [http-bio-8080-exec-10] ERROR [/hello_world]. 
[default] - Servlet.service() for servlet [default] in context with path [/hello_world] threw exception 
Message: Cannot invoke method loadUserByToken() on null object 
Line | Method 
->> 55 | authenticate in grails.plugin.springsecurity.rest.RestAuthenticationProvider 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|  75 | doFilter  in grails.plugin.springsecurity.rest.RestTokenValidationFilter 
|  53 | doFilter . . in grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter 
| 143 | doFilter  in grails.plugin.springsecurity.rest.RestAuthenticationFilter 
|  62 | doFilter . . in grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter 
|  80 | doFilter  in grails.plugin.springsecurity.rest.RestLogoutFilter 
|  59 | doFilter . . in grails.plugin.springsecurity.web.SecurityRequestHolderFilter 
|  82 | doFilter  in com.brandseye.cors.CorsFilter 
| 1142 | runWorker . in java.util.concurrent.ThreadPoolExecutor 
| 617 | run   in java.util.concurrent.ThreadPoolExecutor$Worker 
^ 745 | run . . . . in java.lang.Thread 

ich diesen loadUserByToken() -Methode überprüft, und es wird auf tokenStorageService aufgerufen. Ich habe keine Ahnung, warum dieses TokenStorageService Null-Objekt ist. Die Spring Security und Spring Security Plugin sind wie folgt konfiguriert:

Config.groovy

// Added by the Spring Security Core plugin: 
grails.plugin.springsecurity.userLookup.userDomainClassName = 'hello_world.User' 
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'hello_world.UserRole' 
grails.plugin.springsecurity.authority.className = 'hello_world.Role' 
grails.plugin.springsecurity.controllerAnnotations.staticRules = [ 
    '/':    ['permitAll'], 
    '/index':   ['permitAll'], 
    '/index.gsp':  ['permitAll'], 
    '/assets/**':  ['permitAll'], 
    '/**/js/**':  ['permitAll'], 
    '/**/css/**':  ['permitAll'], 
    '/**/images/**': ['permitAll'], 
    '/**/favicon.ico': ['permitAll'], 
    '/api/login':  ['permitAll'] 
] 

grails { 
    plugin { 
     springsecurity { 

      filterChain.chainMap = [ 
        '/api/guest/**': 'anonymousAuthenticationFilter,restTokenValidationFilter,restExceptionTranslationFilter,filterInvocationInterceptor', 
        '/api/**': 'JOINED_FILTERS,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter', // Stateless chain 
        '/**': 'JOINED_FILTERS,-restTokenValidationFilter,-restExceptionTranslationFilter'                   // Traditional chain 
      ] 

      providerNames = ['restAuthenticationProvider','daoAuthenticationProvider', 'rememberMeAuthenticationProvider'] 

      auth.loginFormUrl = '/login/auth' 

      useSecurityEventListener = true 

      onAuthenticationSuccessEvent = { e, appCtx -> 
       // handle AuthenticationSuccessEvent 

       System.out.println("Authentication Succeeded"); 
      } 

      onAuthenticationSwitchUserEvent = { e, appCtx -> 
       // handle AuthenticationSwitchUserEvent 
      } 

      onAuthorizationEvent = { e, appCtx -> 
       // handle AuthorizationEvent 
      } 

      onRestTokenCreationEvent = { e, appCtx -> 

       System.out.println("Token Created") 
      } 

      apf { 
       filterProcessesUrl = '/api/login' 
       allowSessionCreation = false 
//    usernamePropertyName = 'username' 
//    passwordPropertyName = 'password' 
      } 

      rest { 

       active = true 

       login { 
        active = true 
        endpointUrl = '/api/login' 
        failureStatusCode = 401 
        useJsonCredentials = true 
        usernamePropertyName = 'username' 
        passwordPropertyName = 'password' 
       } 

       token { 

        validation { 
         active = true 
         endpointUrl = '/api/validate' 
         headerName = 'x-auth-token' 
         useBearerToken = false 
         tokenPropertyName = 'access_token' 
         enableAnonymousAccess = true 
        } 

        generation { 
         active = true 
         useSecureRandom = true 
         useUUID = false 
        } 

        rendering { 
         usernamePropertyName = 'username' 
         authoritiesPropertyName = 'roles' 
         tokenPropertyName = 'token' 
        } 

        storage { 
         active = true 
         useGorm = true 

         gorm { 
          tokenDomainClassName = 'hello_world.AuthenticationToken' 
          tokenValuePropertyName = 'tokenValue' 
          usernamePropertyName = 'username' 
         } 
        } 
       } 
      } 
     } 
    } 
} 

resources.groovy

import grails.plugin.springsecurity.rest.RestAuthenticationProvider 
beans = { 
    restAuthenticationProvider(RestAuthenticationProvider); 
} 

und ich habe Datenbank überprüft, wird der Token in authentication_token Tabelle gespeichert. Ich bin neu im Gral und habe Stunden und keine Ahnung gesucht. Kann mir jemand helfen? sehr geschätzt.

Wenn Sie noch etwas brauchen, lassen Sie es mich bitte wissen.

Antwort

1

Für jemanden, der das gleiche Problem hat, nach einer Reihe von Versuchen, habe ich endlich herausgefunden. Es scheint, dass ich restAuthenticationProvider nicht in resources.groovy deklarieren sollte und restAuthenticationProvider nicht zu grails.plugin.springsecurity.providerNames in config.groovy hinzufügen sollte. Die kompletten Konfigurationen für federsicherheits Kern und federsicherheits Rest sind wie folgt aufgeführt:

config.groovy

grails { 
    plugin { 
     springsecurity { 

      useSecurityEventListener = true 

      filterChain { 
       chainMap = [ 
         '/api/**': 'JOINED_FILTERS,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter', // Stateless chain 
         '/**': 'JOINED_FILTERS,-restTokenValidationFilter,-restExceptionTranslationFilter'                   // Traditional chain 
       ] 
      } //filterChain 

      apf { 
       filterProcessesUrl = '/api/login' 
      } //apf 

      rest { 

       login { 
        active = true 
        useRequestParamsCredentials = false 
        useJsonCredentials = true 
        usernamePropertyName = 'j_username' 
        passwordPropertyName = 'j_password' 
        endpointUrl = '/api/login' 
       } //login 

       logout { 

       } //logout 

       token { 

        validation { 
         active = true 
         endpointUrl = '/api/validate' 
         useBearerToken = false 
         headername = 'X-Auth-Token' 
        } //validation 

        generation { 
//      active = true 
//      useSecureRandom = true; 
//      useUUID = false; 
        } 

        rendering { 
         usernamePropertyName = 'username' 
         authoritiesPropertyName = 'roles' 
         tokenPropertyName = 'token' 
        } 

        storage { 
//      useJWT = true; 
        } //storage 
       } //token 
      } //rest 

      cors.headers = ['Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Auth-Token'] 
     } //springsecurity 
    } //plugin 
} //grails 

Sie Benutzername und Passwort im JSON-Format mit dem Feld „j_username“ senden sollen und " j_password "und es wird ein Token im JSON-Format zurückgeben. Dann senden Sie die Anfrage zusammen mit diesem Token im Header-Feld "X-Auth-Token" an die API, die Sie abfragen möchten.

Für die Feder-Sicherheits-Core-Plug-Initialisierung, wenden Sie sich bitte http://grails-plugins.github.io/grails-spring-security-core/v2/guide/single.html#tutorials

ein komplettes meines Codes ist in Github verfügbar: https://github.com/xixinhe/api_token_authentication

Vor meinem Code ausgeführt wird, bitte oracle mysql 5.

installieren

Wenn es etwas gibt, das ich geschrieben habe und die Stack-Überlaufregeln verletzt, lass es mich wissen, ich werde mich ändern.

Ich bin kein englischer Muttersprachler, bitte verzeih mir beschissen Englisch.

Danke,