Grails spring安全自定义会话身份验证

时间:2018-02-15 14:19:34

标签: rest authentication grails spring-security grails-spring-security

我在遗留系统上工作,因此无法遵循Spring Security Core插件(documentation)提供的标准文档,这意味着我不喜欢域名对象。

我正在尝试开发的是基于会话的身份验证的grails中的REST-API(不能使用基本身份验证,因为前端是Angular,并且需要能够在30分钟不活动后使用户无效)

我发现resource正在做我正在尝试做的事情 - 虽然那是使用域对象,这是我正在做的事情。

grails应用程序也将最终在Tomcat服务器上运行,因此也必须与之兼容。

但是,我试图建立自己的身份验证提供程序。我在application.groovy中有以下内容:

grails.plugin.springsecurity.providerNames = ['myAuthenticator','daoAuthenticationProvider']

grails.plugin.springsecurity.rest.login.endpointUrl = '/login'

grails.plugin.springsecurity.filterChain.chainMap = [
    [pattern:'/login',           filters: 'JOINED_FILTERS,-anonymousAuthenticationFilter,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter'], 
    [pattern: '/assets/**',      filters: 'none'],
    [pattern: '/**/js/**',       filters: 'none'],
    [pattern: '/**/css/**',      filters: 'none'],
    [pattern: '/**/images/**',   filters: 'none'],
    [pattern: '/**/favicon.ico', filters: 'none']//,
    [pattern: '/**',             filters: 'JOINED_FILTERS,-anonymousAuthenticationFilter,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter']
]

在resources.groovy中我有

beans = {
    myAuthenticator(MyAuthenticator)
}

我的MyAuthenticator课程:

class MyAuthenticator implements AuthenticationProvider {

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        ArrayList<SimpleGrantedAuthority> simpleGrantedAuthorities = new ArrayList<SimpleGrantedAuthority>();
        simpleGrantedAuthorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"))

        return new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), authentication.getCredentials(), simpleGrantedAuthorities)
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return (authentication == UsernamePasswordAuthenticationToken.class);
    }
}

为了测试这是否有效,我正在解雇一个CURL。

curl -i -H "Content-Type: application/json" --data '{"username":"user","password":"pass"}' http://localhost:8080/login

返回401.日志中的堆栈跟踪如下:

DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/login'; against '/login'
DEBUG o.s.security.web.FilterChainProxy - /login at position 1 of 9 in additional filter chain; firing Filter: 'SecurityRequestHolderFilter'
DEBUG o.s.security.web.FilterChainProxy - /login at position 2 of 9 in additional filter chain; firing Filter: 'MutableLogoutFilter'
DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/login'; against '/logoff'
DEBUG o.s.security.web.FilterChainProxy - /login at position 3 of 9 in additional filter chain; firing Filter: 'RestAuthenticationFilter'
DEBUG g.p.s.rest.RestAuthenticationFilter - Actual URI is /login; endpoint URL is /login
DEBUG g.p.s.rest.RestAuthenticationFilter - Applying authentication filter to this request
DEBUG g.p.s.r.c.DefaultJsonPayloadCredentialsExtractor - Extracted credentials from JSON payload. Username: user,password: [PROTECTED]
DEBUG g.p.s.rest.RestAuthenticationFilter - Trying to authenticate the request
DEBUG o.s.s.authentication.ProviderManager - Authentication attempt using MyAuthenticator
DEBUG g.p.s.rest.RestAuthenticationFilter - Request authenticated. Storing the authentication result in the security context
DEBUG g.p.s.rest.RestAuthenticationFilter - Authentication result: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@4095914d: Principal: user; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN
DEBUG g.p.s.r.t.g.j.AbstractJwtTokenGenerator - Generating an access token with default expiration: 3600
DEBUG g.p.s.r.t.g.j.AbstractJwtTokenGenerator - Serializing the principal received
ERROR o.a.c.c.C.[.[.[.[grailsDispatcherServlet] - Servlet.service() for servlet [grailsDispatcherServlet] in context with path [] threw exception
groovy.lang.MissingMethodException: No signature of method: java.lang.String.getUsername() is applicable for argument types: () values: []
        at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:58)
        at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:64)
        at org.codehaus.groovy.runtime.callsite.PogoGetPropertySite.getProperty(PogoGetPropertySite.java:52)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:296)
        at grails.plugin.springsecurity.rest.token.generation.jwt.AbstractJwtTokenGenerator.generateClaims(AbstractJwtTokenGenerator.groovy:67)
        at grails.plugin.springsecurity.rest.token.generation.jwt.AbstractJwtTokenGenerator$generateClaims$1.callCurrent(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:182)
        at grails.plugin.springsecurity.rest.token.generation.jwt.AbstractJwtTokenGenerator.generateAccessToken(AbstractJwtTokenGenerator.groovy:51)
        at grails.plugin.springsecurity.rest.token.generation.jwt.AbstractJwtTokenGenerator$generateAccessToken$0.callCurrent(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:182)
        at grails.plugin.springsecurity.rest.token.generation.jwt.AbstractJwtTokenGenerator.generateAccessToken(AbstractJwtTokenGenerator.groovy:44)
        at grails.plugin.springsecurity.rest.token.generation.jwt.AbstractJwtTokenGenerator$generateAccessToken.callCurrent(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:174)
        at grails.plugin.springsecurity.rest.token.generation.jwt.AbstractJwtTokenGenerator.generateAccessToken(AbstractJwtTokenGenerator.groovy:39)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1426)
        at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSite.invoke(PogoMetaMethodSite.java:169)
        at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.call(PogoMetaMethodSite.java:71)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
        at grails.plugin.springsecurity.rest.RestAuthenticationFilter.doFilter(RestAuthenticationFilter.groovy:130)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
        at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.groovy:62)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
        at grails.plugin.springsecurity.web.SecurityRequestHolderFilter.doFilter(SecurityRequestHolderFilter.groovy:58)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213)
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
        at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:75)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
        at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
        at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:103)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
        at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:745)

如图所示,它确实认为它在错误发生前不久就会进行身份验证。但是,然后某个地方出现了问题,并尝试在String上执行.getUsername()。

我无法弄清楚是什么尝试这样做的。我会很感激任何可能导致这个问题的想法,或者即使我以完全错误的方式解决它。

0 个答案:

没有答案