我刚刚在项目中添加了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程序并且它们有效)!请帮我 !感谢。
答案 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) {
}
});