[英]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.