求助,shiro报错org.apache.shiro.UnavailableSecurityManagerException,帮忙看一下

码旺 2016-03-28 11:47:59
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- Shiro的核心安全接口,这个属性是必须的 -->
<property name="securityManager" ref="securityManager"/>
<!-- 要求登录时的链接(可根据项目的URL进行替换),非必须的属性,默认会自动寻找Web工程根目录下的"/login.jsp"页面 -->
<property name="loginUrl" value="/user/login.do"/>
<!-- 登录成功后要跳转的连接(本例中此属性用不到,因为登录成功后的处理逻辑在LoginController里硬编码了) -->
<property name="successUrl" value="/system/pay.do"/>
<!-- 用户访问未对其授权的资源时,所显示的连接 -->
<property name="unauthorizedUrl" value="/page/error/401.jsp"/>
<!-- Shiro连接约束配置,即过滤链的定义 -->
<!-- 下面value值的第一个'/'代表的路径是相对于HttpServletRequest.getContextPath()的值来的 -->
<!-- anon:它对应的过滤器里面是空的,什么都没做,这里.do和.jsp后面的*表示参数,比方说login.jsp?main这种 -->
<!-- authc:该过滤器下的页面必须验证后才能访问,它是Shiro内置的一个拦截器org.apache.shiro.web.filter.authc.FormAuthenticationFilter -->
<property name="filters">
<util:map>
<entry key="authc" value-ref="loginAuthenticationFilter"/>
<entry key="examine" value-ref="loginExamineFilter"/>
<entry key="anyRoles" value-ref="anyRoles"/>
<!--<entry key="ssl" value-ref="sslFilter"/>-->
</util:map>
</property>


<property name="filterChainDefinitions">
<value>
<!-- 登陆拦截 -->
<!-- /**=ssl -->
/user/toLogin**=examine,authc

<!-- 退出拦截 -->
/user/logout**=logout

<!-- 登陆判断拦截,如果已经登陆跳转至主页面 -->
/page/jsp/login.jsp**=examine
/user/login**=examine

<!-- 无需拦截 -->
/jcaptcha**=anon
/host/toRegister.do=anon
/host/register.do=anon
/host/toChangePwd.do=anon
/host/checkInviteCode.do=anon
/host/checkHostName.do=anon
/host/consume.do=anon
/host/findAllAreasInfo.do=anon
/host/findAllAreasInfoPid/**=anon
/host/checkEmployeeBean.do=anon
/host/checkValidateCodecode.do=anon
/client/toUpdate.do=anon
/client/toUpdate2.do=anon
/client/changePassword.do=anon
/system/left.do=anon
/**/error/*.jsp=anon

<!-- 权限拦截 -->

/account/**=roles[communal]
/userRole/**=anyRoles[admin,isShopMan]

<!-- 页面拦截,给角色赋予了权限才能登陆此页面
而在LoginRealm中使用的是Permission而不是Role
-->
/order/index.do=roles[orderIn]
/product/select.do=roles[productManage]
/product/consume.do=roles[consume]
/product/member.do=roles[member]
/product/storage.do=roles[storage]
/system/pay.do=roles[localPay]
/account/index.do=roles[bllAccount]
/account/toMoneyMove.do=roles[moneyMove]
/client/tohuiyuan.do=roles[procurement]
/account/withdrawMoney.do=roles[withdrawMoney]
/userRole/toclerklist.do=roles[clerkManage]
/account/index.do=roles[bllBalance]
/invite/index.do=roles[registeRaudit]
/invite/showHostInfo.do=roles[hostInfoaudit]
/invite/showClientInfo.do=roles[bllNewsUpdate]
/role/tolist.do=roles[roleManage]
/userRole/tolist.do=roles[userManage]
/account/financeToMoney.do=roles[financeToMoney]
/invite/bllAllot.do=roles[bllAllot]

<!-- 域名访问,未登录跳转登陆页面,已登陆根据角色跳转对应主页面 -->
/=examine
</value>
</property>
</bean>



<bean id="sslFilter" class="org.apache.shiro.web.filter.authz.SslFilter">
<property name="port" value="8443"/>
</bean>

<bean id="loginAuthenticationFilter" class="com.ssxt.ycfxf.host.filter.LoginAuthenticationFilter">
<property name="loginUrl" value="/user/toLogin.do"/>
</bean>
<bean id="loginExamineFilter" class="com.ssxt.ycfxf.host.filter.LoginExamineFilter">
</bean>

<!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

<bean id="loginRealm" class="com.ssxt.ycfxf.host.realm.LoginRealm"></bean>

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="loginRealm"/>
</bean>

<!--自定义的Roles Filter-->
<bean id="anyRoles" class="com.ssxt.ycfxf.host.filter.CustomRolesAuthorizationFilter" />

</beans>


而在LoginRealm中页面拦截我使用的是Permission而不是Role,而且是通过从数据库里面取出动态获取的。
LoginRealm代码如下
public class LoginRealm extends AuthorizingRealm {

@Autowired
private UserService userService;

@Autowired
private RegisterInfoService registerInfoService;

@Autowired
private EmpRoleService empRoleService;

@Autowired
private RoleService roleService;

@Autowired
private MenuService menuService;

@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
HostEmployeeBean he = (HostEmployeeBean) principals.getPrimaryPrincipal();

if (he != null) {
EmployeeBean emp = registerInfoService.findEmployeeByUserName(he.getUserName());
EmpRole empRole = empRoleService.findEmpRoleByEmpId(emp.getId());
Role role = roleService.getRoleById(empRole.getRoleId());
// List<String> perms =menuService.getPermsByRoleid(empRole.getRoleId());
List<Map<String, Object>> menus =menuService.getPermsByRoleid(empRole.getRoleId());
if(role != null) {
int status = role.getRoleStatus();
if(status == 0 || status == 2) {
// 后台管理员登陆
info.addRole(Constant.SPECIAL_ROLE);
info.addRole("communal");
} else {
//店铺方登录
info.addRole(Constant.ORDINARY_ROLE);
info.addRole("communal");
/* info.addRole(Constant.MODEL_POWER);*/
if(role.getName().equals(PropertiesUtil.propertiesMessage("isShopMan"))) {
info.addRole(Constant.MODEL_POWER);
}
}
}
else {
//店铺方登录
info.addRole(Constant.ORDINARY_ROLE);
info.addRole("communal");

}
if (menus != null && menus.size() > 0) {
for (Map<String, Object> m : menus) {
if(m !=null && ((String)m.get("id")).length()==3){
info.addRole((String)m.get("perName"));
} else if(m !=null && ((String)m.get("id")).length()==5){
//这里使用的是Permission而不是Role
info.addStringPermission((String)m.get("perName"));
}
}
}

}
return info;
}

@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
String password = new String((char[]) upToken.getPassword());
String username = upToken.getUsername();
if(StringUtils.isEmpty(password) && StringUtils.isEmpty(username)){
// 前期验证出错,直接抛出异常让Controller处理
throw new AuthenticationException();
}

// 查询数据库
HostEmployeeBean he = userService.login(username, password);
if (he != null && he.getEmpId() != null && !"".equals(he.getEmpId().trim())) {
// 登陆成功,保存用户信息到Shiro对象中
return new SimpleAuthenticationInfo(he, password, getName());
} else {
// 用户名或密码有误,登陆失败
throw new UnknownAccountException();
}
}

@Override
public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
super.clearCachedAuthorizationInfo(principals);
}

@Override
public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
super.clearCachedAuthenticationInfo(principals);
}

@Override
public void clearCache(PrincipalCollection principals) {
super.clearCache(principals);
}

public void clearAllCachedAuthorizationInfo() {
getAuthorizationCache().clear();
}

public void clearAllCachedAuthenticationInfo() {
getAuthenticationCache().clear();
}

public void clearAllCache() {
clearAllCachedAuthenticationInfo();
clearAllCachedAuthorizationInfo();
}
}


然后打开赋予权限的页面就会报错:
严重: Servlet.service() for servlet jsp threw exception
org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager accessible to the calling code, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton. This is an invalid application configuration.
at org.apache.shiro.SecurityUtils.getSecurityManager(SecurityUtils.java:123)
at org.apache.shiro.subject.Subject$Builder.<init>(Subject.java:627)
at org.apache.shiro.SecurityUtils.getSubject(SecurityUtils.java:56)

Caused by: org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager accessible to the calling code, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton. This is an invalid application configuration.
at org.apache.shiro.SecurityUtils.getSecurityManager(SecurityUtils.java:123)

但是对项目运行无影响,我调试了半天也没弄好,大神们帮忙看看是哪里出问题了,在线等

...全文
4718 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Z. ZHANG 2017-02-18
  • 打赏
  • 举报
回复
引用 7 楼 yehuoaa 的回复:
你好,这个问题怎么解决的?可以分享下吗?
因为没有调用SecurityManager 加上
<!-- 相当于调用SecurityUtils.setSecurityManager(securityManager) -->
	<bean
		class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
		<property name="staticMethod"
			value="org.apache.shiro.SecurityUtils.setSecurityManager" />
		<property name="arguments" ref="securityManager" />
	</bean>
一些其他问题可以看这个http://blog.csdn.net/zzhao114/article/details/55662585
yehuoaa 2017-02-09
  • 打赏
  • 举报
回复
你好,这个问题怎么解决的?可以分享下吗?
码旺 2016-03-30
  • 打赏
  • 举报
回复
引用 4 楼 sansanhehe 的回复:
[quote=引用 3 楼 yaoyao9565 的回复:] 没人知道问题么。。。怎么没有人回答啊
hehe[/quote] 呵呵个毛线啊~33呵呵~
sansanhehe 2016-03-30
  • 打赏
  • 举报
回复
引用 3 楼 yaoyao9565 的回复:
没人知道问题么。。。怎么没有人回答啊
hehe
码旺 2016-03-30
  • 打赏
  • 举报
回复
没人知道问题么。。。怎么没有人回答啊