Apache
Shiro使用的默认EnvironmentLoaderListener不支持CDI。解决方案是构建一个,然后替换web.xml中的原始引用以指向您的自定义引用。
注意:
侦听器自动支持CDI注入,但是侦听器必须通过CDI机制请求bean。定制侦听器将用于
@Inject请求bean,并将创建
JpaRealm为CDI
bean,并将注入所有依赖项。默认的Shire侦听器不会通过创建
JpaRealm为启用CDI的bean
@Inject。
CustomCredentialsMatcher.java
public class CustomCredentialsMatcher extends SimpleCredentialsMatcher {}CustomEnvironmentLoaderListener.java
public class CustomEnvironmentLoaderListener extends EnvironmentLoaderListener { @Inject private JpaRealm jpaRealm; @Override protected WebEnvironment createEnvironment(ServletContext pServletContext) { WebEnvironment environment = super.createEnvironment(pServletContext); RealmSecurityManager rsm = (RealmSecurityManager) environment.getSecurityManager(); PasswordService passwordService = new DefaultPasswordService(); PasswordMatcher passwordMatcher = new PasswordMatcher(); passwordMatcher.setPasswordService(passwordService); jpaRealm.setCredentialsMatcher(passwordMatcher); rsm.setRealm(jpaRealm); ((DefaultWebEnvironment) environment).setSecurityManager(rsm); return environment; }}FacesAjaxAwareUserFilter.java
public class FacesAjaxAwareUserFilter extends UserFilter { private static final String FACES_REDIRECT_XML = "<?xml version="1.0" encoding="UTF-8"?><partial-response><redirect url="%s"></redirect></partial-response>"; @Override protected void redirectToLogin(ServletRequest req, ServletResponse res) throws IOException { HttpServletRequest request = (HttpServletRequest) req; if ("partial/ajax".equals(request.getHeader("Faces-Request"))) { res.setContentType("text/xml"); res.setCharacterEncoding("UTF-8"); res.getWriter().printf(FACES_REDIRECT_XML, request.getContextPath() + getLoginUrl()); } else { super.redirectToLogin(req, res); } }}JpaRealm.java
public class JpaRealm extends AuthorizingRealm { private static String REALM_NAME = "jpaRealm"; @Inject private UserDao userDao; @Inject private RoleDao roleDao; @Inject private PermissionDao permissionDao; public JpaRealm() { setName(REALM_NAME); // This name must match the name in the User class's getPrincipals() method } protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authToken) throws AuthenticationException { UsernamePasswordToken token = (UsernamePasswordToken) authToken; User user = userDao.getForUsername(token.getUsername()); if (user != null) { return new SimpleAuthenticationInfo(user.getId(), user.getPassword(), getName()); } else { return null; } } protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { Long userId = (Long) principals.fromRealm(getName()).iterator().next(); User user = userDao.findByKey(userId); if (user != null) { SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); for (Role role : roleDao.getForUser(user)) { info.addRole(role.getDescription()); for (Permition permition : permissionDao.getForRole(role)) { info.addStringPermission(permition.getDescription()); } } return info; } else { return null; } }}shiro.ini
[main]user = com.boss.mrfoods.security.FacesAjaxAwareUserFilteruser.loginUrl = /pages/public/login.xhtml[urls]/index.html = anon/pages/index.xhtml = anon/pages/public/** = anon/pages/admin/** = user, roles[ADMIN]/pages/user/** = user, roles[USER]
web.xml
...<listener> <listener-class>com.boss.mrfoods.security.CustomEnvironmentLoaderListener</listener-class></listener><filter> <filter-name>ShiroFilter</filter-name> <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class></filter><filter-mapping> <filter-name>ShiroFilter</filter-name> <url-pattern>/*</url-pattern></filter-mapping>...



