将Shiro添加到Eclipse java项目中 - 根本没有错误消息用于诊断

时间:2014-08-26 13:01:23

标签: console shiro

我刚刚在项目中添加了Shiro,在WEB-INF / lib(shiro-core和shiro-web)中添加了两个jar,自定义了web.xml,并在WEB-INF文件夹中添加了shiro.ini。我还使用shiro:guest标签编写了一个带有登录表单的ad hoc menu.jsp。问题是,当我启动应用程序,并在表单中插入用户名和密码时,为了登录,没有任何反应,控制台中根本没有显示任何消息。所以我很难对问题做出诊断。我该怎么做才能继续?

web.xml is the following:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <display-name>photoalbum</display-name>

    <servlet>
        <servlet-name>action</servlet-name>
        <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
        <init-param>
            <param-name>config</param-name>
            <param-value>/WEB-INF/struts/struts-config.xml</param-value>
        </init-param>
        <init-param>
            <param-name>chainConfig</param-name>
            <param-value>org/apache/struts/tiles/chain-config.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>action</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

    <listener>
        <listener-class>it.univaq.mwt.bcd.photoalbum.common.startup.PhotoAlbumServletContextListener</listener-class>
    </listener>

    <listener>
        <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</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>*.do</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping>

    <welcome-file-list>
        <welcome-file>index.do</welcome-file>
    </welcome-file-list>
</web-app>

shiro.ini是以下

[main]
authc.loginUrl = /index.do
authc.successUrl  = /common/welcome.do
myroles= it.univaq.mwt.bcd.photoalbum.common.shiro.MyRolesAuthorizationFilter 
myRealm = it.univaq.mwt.bcd.photoalbum.common.shiro.MyAuthorizingRealm
securityManager.realms = $myRealm


[users]
#borrower = borrower, borrower
#librarian = librarian, librarian
#masterlibrarian = masterlibrarian, masterlibrarian
#RegisteredUser = RegisteredUser


[roles]
#borrower = *
#librarian = *
#masterlibrarian = *
#RegisteredUser = *

[urls]
/index.do = authc
/logout.do = logout
/common/** = authc, myroles[librarian, masterlibrarian, borrower, RegisteredUser]
/titles/** = authc, myroles[librarian,masterlibrarian, RegisteredUser]
/borrowers/** = authc, myroles[librarian, masterlibrarian, RegisteredUser]
/items/** = authc, myroles[librarian, masterlibrarian, RegisteredUser]
/librarians/** = authc, myroles[masterlibrarian, RegisteredUser]
/items/checkoutitem.do = authc, myroles[borrower]
/items/returntitem.do = authc, myroles[borrower]

menu.jsp如下:

<%@taglib uri="http://shiro.apache.org/tags" prefix="shiro"%>
<%@taglib uri="http://struts.apache.org/tags-bean" prefix="bean"%>
<div class="navbar navbar-inverse navbar-fixed-top" >
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="${pageContext.request.contextPath}/common/welcome.do"><bean:message key="common.title" /></a>
        </div>
        <div class="navbar-collapse collapse">
            <shiro:authenticated>
                <ul class="nav navbar-nav">
                    <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown"><bean:message key="menu.home" /><b class="caret"></b></a>
                        <ul class="dropdown-menu">
                        <li>                                <a
                                    href="${pageContext.request.contextPath}/registered/profile.do">
                                    <bean:message key="menu.profile" />
                                </a>
                            </li>
                            <li>
                                <a
                                    href="${pageContext.request.contextPath}/registered/uploadform.do">
                                    <bean:message key="menu.upload" />
                                </a>
                            </li>
                        </ul>
                    </li>

                    <shiro:hasRole name="RegisteredUser">
                        <li><a href="${pageContext.request.contextPath}/registered/listresource.do"><bean:message key="menu.list" /></a></li>   
                        <li><a href="${pageContext.request.contextPath}/registered/commentresource.do"><bean:message key="menu.comment" /></a></li>
                        <li><a href="${pageContext.request.contextPath}/registered/gallery.do"><bean:message key="menu.gallery" /></a></li>     
                    </shiro:hasRole>
                    <shiro:hasRole name="Admin">
                </shiro:hasRole>
            <li><a href="${pageContext.request.contextPath}/logout.do"><bean:message key="menu.logout" /></a></li>
                </ul>
            </shiro:authenticated>

            <shiro:guest>

                <form name="loginform" action="${pageContext.request.contextPath}/index.do" method="post" class="navbar-form navbar-right" >
                    <div class="form-group">
                        <input type="text" placeholder="Username" class="form-control" name="j_username">
                    </div>
                    <div class="form-group">
                        <input type="password" placeholder="Password" class="form-control" name="j_password">
                    </div>
                    <button type="submit" class="btn btn-success">
                        <bean:message key="common.signin" />
                    </button>
                </form>
            </shiro:guest>


        </div>
        <!--/.navbar-collapse -->
    </div>
</div>

我也有这两个java程序(不是我)使shiro.ini

工作
package it.univaq.mwt.bcd.photoalbum.common.shiro;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import it.univaq.mwt.bcd.photoalbum.business.BusinessException;
import it.univaq.mwt.bcd.photoalbum.business.LibraryBusinessFactory;
import it.univaq.mwt.bcd.photoalbum.business.PhotoAlbumBusinessFactory;
import it.univaq.mwt.bcd.photoalbum.business.SecurityService;
import it.univaq.mwt.bcd.photoalbum.business.model.Role;
import it.univaq.mwt.bcd.photoalbum.business.model.User;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.Permission;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

public class MyAuthorizingRealm extends AuthorizingRealm {

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        SecurityService service = PhotoAlbumBusinessFactory.getInstance().getSecurityService();

        User user = null;
        try {
            user = service.authenticate(upToken.getUsername());
        } catch (BusinessException idEx) {
            throw new AuthenticationException(idEx);
        } 

        if (user == null) {
            throw new AuthenticationException("Login name [" + upToken.getUsername() + "] not found!");
        }

        return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        Set<String>         roles           = new HashSet<String>();
        Set<Permission>     permissions     = new HashSet<Permission>();
        Collection<User>    principalsList  = principals.byType(User.class);

        if (principalsList.isEmpty()) {
            throw new AuthorizationException("Empty principals list!");
        }
        SecurityService service = PhotoAlbumBusinessFactory.getInstance().getSecurityService();
        //LOADING STUFF FOR PRINCIPAL 
        for (User userPrincipal : principalsList) {
            try {

                User user = service.authenticate(userPrincipal.getUsername());

                Set<Role> userRoles = user.getRoles();
                for (Role r : userRoles) {
                    roles.add(r.getName());
                }
            } catch (BusinessException idEx) { //userManger exceptions
                throw new AuthorizationException(idEx);
            } 
        }
        //THIS IS THE MAIN CODE YOU NEED TO DO !!!!
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roles);
        info.setRoles(roles); //fill in roles 
        info.setObjectPermissions(permissions); //add permissions (MUST IMPLEMENT SHIRO PERMISSION INTERFACE)

        return info;
    }

}

以及以下内容:

package it.univaq.mwt.bcd.photoalbum.common.shiro;

import java.io.IOException;
import java.util.Set;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;

public class MyRolesAuthorizationFilter extends AuthorizationFilter {

    @SuppressWarnings({"unchecked"})
    public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {

        Subject subject = getSubject(request, response);
        String[] rolesArray = (String[]) mappedValue;

        if (rolesArray == null || rolesArray.length == 0) {
            //no roles specified, so nothing to check - allow access.
            return true;
        }

        Set<String> roles = CollectionUtils.asSet(rolesArray);

        for (String role : roles) {
            if (subject.hasRole(role)) {
                return true;
            }
        }
        return false;
    }

}

我唯一怀疑的是这两个java程序是否适合我的应用程序(我在另一个java项目中使用了这两个java程序并且它们有效)!请帮我 !感谢。

1 个答案:

答案 0 :(得分:0)

可能是您是以下错误的受害者:

https://issues.apache.org/jira/browse/SHIRO-467

您的自定义域中可能发生的身份验证异常会被shiro吞噬。

有一种解决方法可以让抛出的异常对我们有用。如果你可以在启动方法的某个地方获取securityManager对象(我们使用spring,所以我们使用配置类,但你可能能够使用servlet上下文监听器或类似的东西)。 在安全管理器上,注册一个身份验证监听器,如下所示:

    AbstractAuthenticator abstractAuthenticator = (AbstractAuthenticator) securityManager.getAuthenticator();
    abstractAuthenticator.getAuthenticationListeners().add(new AuthenticationListener() {
        @Override
        public void onSuccess(AuthenticationToken token, AuthenticationInfo info) {
        }

        @Override
        public void onFailure(AuthenticationToken token, AuthenticationException ae) {
            if (ae.getCause() != null) {
                //log exception or do ae.printStackTrace(), we log it:
                LOG.error("Problem during authenticating {}", token, ae);
            }
        }

        @Override
        public void onLogout(PrincipalCollection principals) {
        }
    });