当前位置: 首页 > 面试题库 >

无法在自定义Apache Shiro AuthorizingRealm中@Inject我的DAO

赵钊
2023-03-14
问题内容

我试图将我的UserDAO注入Apache Shiro正在使用的自定义AuthorizingRealm中,但是…我得到了空值。

我究竟做错了什么?

shiro.ini

[main]
user = demo.shiro.security.FacesAjaxAwareUserFilter
realmA = demo.shiro.security.JpaRealm
credentialsMatcher = org.apache.shiro.authc.credential.SimpleCredentialsMatcher
realmA.credentialsMatcher = $credentialsMatcher
securityManager.realms = $realmA
user.loginUrl = /pages/public/login.xhtml

[users]
admin = admin
user = user

[urls]
# public files and folders
/index.html = anon
/resources/** = anon
/pages/public/** = anon

# restricted files and folders
/pages/admin/** = user
/pages/user/** = user

JpaRealm.java

public class JpaRealm extends AuthorizingRealm {

    @Inject
    private UserDao userDao;

    public JpaRealm() {
        setCredentialsMatcher(new Sha256CredentialsMatcher());
    }

    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 : user.getRoles()) {
                info.addRole(role.getDescription());
                for (Permition permition : role.getPermitions()) {
                    info.addStringPermission(permition.getDescription());
                }
            }
            return info;
        } else {
            return null;
        }
    }

}

我该怎么做才能使CDI了解自定义领域内的@Inject并正确注入UserDAO?


问题答案:

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.FacesAjaxAwareUserFilter
user.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>
...


 类似资料:
  • 我正在做一个连接到documentum数据存储的JavaFx项目。我需要从数据存储中检索一些数据,插入并以表格形式组织它们,我使用的是网格。由于数据因对象而异,我必须使代码动态,并使用编程GUI设计。好吧,在数据获取和上传到GridPane中没有问题。但是,我在设计该GridPan的界面时遇到了一些问题。我在FXML文件中创建了一个名为“aclInfo”的GridPanes,并试图在其中创建新的G

  • 我正试图将我的UserDAO注入到ApacheShiro正在使用的自定义授权域中,但是。。。我得到空值。 我做错了什么? 西罗。伊尼 jparelm。JAVA 我必须做些什么才能让CDI在我的自定义域中意识到@Inject并正确地注入我的UserDAO?

  • 我使用以下代码来设置jTable中的备用背景行颜色: 它是有效的。但是,我想使用自定义颜色(如rgb(242242))代替浅灰色作为替代颜色,但在执行以下操作时: 替代颜色完全被忽略,所有行都有白色背景。看起来此方法仅适用于属于颜色枚举的颜色。怎么会这样? 下面是一个完整的工作示例,随后是结果屏幕:

  • 问题内容: 我正在阅读另一个SO问题,即Swift do-try-catch语法。在他的回答中, rickster 为OP的自定义类创建了扩展。 Konrad77 评论说,这是“保持代码整洁的好方法。” 我尊重他们的知识,这使我相信我在自己的代码中遗漏了一点。 除了为我创建的类创建扩展之外,还有其他好处(除了整洁)还是原因?我可以将相同的功能直接放入类中。如果我是唯一使用该类的人,或者其他人将使用

  • 我正在开发一个使用Xamarin的自定义键盘。 我的键盘视图对视图容器本身及其子键视图都有一个覆盖的OnDraw()。我还为每个视图适当地使用SetWillNotDraw(false)。它目前在我的Nexus 10平板电脑上的5.0.1中运行良好。 在Android 6.0.1中,在Nexus 6和Nexus 6P上,键盘视图可以正确地绘制自身(只是背景颜色)。然而,即使我遍历视图层次结构并强制对