ServletRequestListener - 获取userprincipal返回null
问题描述:
我有一个使用HTTP-Basic身份验证进行安全保护的Web应用程序。 我还实现了一个使用ServletRequestListener
接口的过滤器。现在,当过滤器调用requestInitialized
方法时,请求的getUserPrincipal-Method返回null。但是,当我检查请求标头时,授权标头设置为加密值。代码如下:ServletRequestListener - 获取userprincipal返回null
@Override
public void requestInitialized(ServletRequestEvent e) {
HttpServletRequest request = (HttpServletRequest) e.getServletRequest();
//p is null
Principal p = request.getUserPrincipal();
Enumeration<String> enH = request.getHeaders("Authorization");
while (enH.hasMoreElements()) {
String s = enH.nextElement();
System.out.println(s);
//prints.
//Basic c3RhY2tvdmVyZmxvdzpteXBhc3N3b3Jk
}
}
为什么userprincipal未初始化?
答
您可能不会为嵌入式码头设置所需的安全层。
这是在Jetty embedded examples source tree中找到的example。
package org.eclipse.jetty.embedded;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.jetty.security.ConstraintMapping;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.security.LoginService;
import org.eclipse.jetty.security.authentication.BasicAuthenticator;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.security.Constraint;
public class SecuredHelloHandler
{
public static void main(String[] args) throws Exception
{
Server server = new Server(8080);
LoginService loginService = new HashLoginService("MyRealm","src/test/resources/realm.properties");
server.addBean(loginService);
ConstraintSecurityHandler security = new ConstraintSecurityHandler();
server.setHandler(security);
Constraint constraint = new Constraint();
constraint.setName("auth");
constraint.setAuthenticate(true);
constraint.setRoles(new String[]{"user", "admin"});
ConstraintMapping mapping = new ConstraintMapping();
mapping.setPathSpec("/*");
mapping.setConstraint(constraint);
Set<String> knownRoles = new HashSet<String>();
knownRoles.add("user");
knownRoles.add("admin");
security.setConstraintMappings(Collections.singletonList(mapping), knownRoles);
security.setAuthenticator(new BasicAuthenticator());
security.setLoginService(loginService);
security.setStrict(false);
// Your Handler (or Servlet) that should be secured
HelloHandler hh = new HelloHandler();
security.setHandler(hh);
server.start();
server.join();
}
}
答
我解决它通过使用过滤器,而不是监听的..
@WebFilter(urlPatterns = { "/*" })
public class RequestFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain fChain) throws IOException, ServletException {
HttpServletRequest hReq = (HttpServletRequest) req;
//p is not null anymore
Principal p = hReq.getUserPrincipal();
fChain.doFilter(hReq, res);
}
@Override
public void destroy() {
}
@Override
public void init(FilterConfig config) throws ServletException {
}
}
在嵌入的码头将如何设置是有用的一些细节。知道你可能需要设置一个LoginService + Constraint + ConstraintMapping + Roles + ConstraintSecurityHandler ... [示例](http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree /examples/embedded/src/main/java/org/eclipse/jetty/embedded/SecuredHelloHandler.java) –