简体   繁体   English

以编程方式在过滤器中的Spring Security中登录用户

[英]Programmatically login user in Spring Security in a Filter

I am trying to implement a filter to programmatically login a user based on certain criteria. 我正在尝试实现一个过滤器,以编程方式基于某些条件登录用户。

This is my filter-method: 这是我的过滤方法:

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    HttpServletResponse response = (HttpServletResponse) servletResponse;
    Cookie[] cookies = request.getCookies();

    boolean typo3loggedin = true;
    String memberNo = "100003";

    HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response);
    SecurityContext securityContext = contextRepository.loadContext(holder);
    Authentication authentication = securityContext.getAuthentication();


    if (cookies != null && cookies.length > 0 ) {
        for (int i = 0; i < cookies.length; i++) {
            String name = cookies[i].getName();
            String value = cookies[i].getValue();
            if (name.equalsIgnoreCase("fe_typo_user")) typo3loggedin = true; //
            logger.debug(String.format("cookie-name: %s, cookie-value: %s", name, value));
        }
    }

    if (typo3loggedin && (authentication == null || !authentication.isAuthenticated())) {
        List<GrantedAuthority> grantedAuths = new ArrayList<GrantedAuthority>();
        grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER"));
        if (authentication == null ) authentication = new UsernamePasswordAuthenticationToken(memberNo, "", grantedAuths);
        securityContext.setAuthentication(authentication);
        contextRepository.saveContext(securityContext, request, response);
        logger.debug("Logged-in from typo3 as user " + memberNo);
    }

    filterChain.doFilter(servletRequest, servletResponse);
}

But whenever I try to save the Authentication, I get the following error: 但每当我尝试保存身份验证时,我都会收到以下错误:

    java.lang.ClassCastException: org.mortbay.jetty.Response cannot be cast to org.springframework.security.web.context.SaveContextOnUpdateOrErrorResponseWrapper
            at org.springframework.security.web.context.HttpSessionSecurityContextRepository.saveContext(HttpSessionSecurityContextRepository.java:108)
            at com.scaratec.bueroprint.mdb.ui.server.filter.SsoFilter.doFilter(SsoFilter.java:74)
            at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
            at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
            at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1212)
            at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:233)
            at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
            at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1212)
            at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
            at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
            at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1212)
            at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:399)
            at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
            at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
            at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:766)
            at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:450)
            at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
            at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
            at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
            at org.mortbay.jetty.Server.handle(Server.java:326)
            at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
            at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:928)
            at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:549)
            at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
            at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
            at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:410)
            at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

The exception message itself doesn't make any sense to me since org.mortbay.jetty.Response implements HttpServletResponse which is taken as parameter to saveContext() . 异常消息本身对我没有任何意义,因为org.mortbay.jetty.Response实现了HttpServletResponse ,它被作为saveContext()参数。

UPDATE: As suggested in the comments below, I have extended the AbstractPreAuthenticatedProcessingFilter which is made for exactly this scenario. 更新:正如下面的评论中所建议的,我已经扩展了AbstractPreAuthenticatedProcessingFilter ,它就是针对这种情况而设计的。 This totally solved my problem. 这完全解决了我的问题。

It looks like a simple class cast issue. 它看起来像一个简单的类转换问题。 The request object isn't an instance of SaveContextOnUpdateOrErrorResponseWrapper . 请求对象不是SaveContextOnUpdateOrErrorResponseWrapper的实例。 This class is use to wrap the request as it passes through the Spring Security filter chain - it's created by the SecurityContextPersistenceFilter . 此类用于在请求通过Spring Security过滤器链时包装请求 - 它由SecurityContextPersistenceFilter创建。

It looks like the call to the SecurityContextRepository originates in a call from your own filter class and the request hasn't passed through the security filter chain (looking at the stacktrace, there is no mention of Spring Security filters). 看起来对SecurityContextRepository的调用源于您自己的过滤器类的调用,并且请求通过安全过滤器链(查看堆栈跟踪,没有提及Spring Security过滤器)。 Hence the request object is still of the original container type, rather than the wrapper. 因此,请求对象仍然是原始容器类型,而不是包装器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM