shiro权限问题

c15852462458 2017-02-17 04:32:55
未登入时,访问 http://192.168.20.110:8080/system/user/getUserList 或者http://192.168.20.110:8080/system/user/getUserList.do 时,都能跳转到登入页面。

使用一个没有此权限的帐号登入,访问 http://192.168.20.110:8080/system/user/getUserList 时,能跳转到无权限的403页面。访问 http://192.168.20.110:8080/system/user/getUserList.do 时,可以直接访问页面内容。

问题是权限交给shiro管理后,没有权限的页面请求或数据请求,正常访问时可以跳转无权限页面,只要加上点,或者加上任意后缀就可以访问到内容,是我的配置有啥问题吗?

web.xml配置

<?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_3_0.xsd"
version="3.0">

<display-name>system</display-name>

<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>

<!-- 初始化监听器 -->
<listener>
<listener-class>system.listener.InitListener</listener-class>
</listener>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>

<servlet>
<servlet-name>spring_mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>spring_mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- 出错页面定义 -->
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/WEB-INF/view/error/500.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/WEB-INF/view/error/500.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/view/error/404.jsp</location>
</error-page>
<error-page>
<error-code>403</error-code>
<location>/WEB-INF/view/error/403.jsp</location>
</error-page>

</web-app>


shiro.xml配置

<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
default-lazy-init="true">

<description>Shiro安全配置</description>

<!-- 使用默认的WebSecurityManager -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="myShiroRealm" />
<!-- cacheManager,集合spring缓存工厂 -->
<!-- <property name="cacheManager" ref="shiroEhcacheManager" /> -->
</bean>

<!-- 自定义Realm -->
<bean id="myShiroRealm" class="system.shiro.MyShiroRealm" />

<!-- Shiro Filter id必须和 web.xml的filter-name一致 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- shiro的核心安全接口 -->
<property name="securityManager" ref="securityManager" />
<!-- 要求登录时的链接 -->
<property name="loginUrl" value="/toLogin" />
<!-- 登陆成功后要跳转的连接 -->
<property name="successUrl" value="/index" />
<!-- 没有权限要跳转的链接 -->
<property name="unauthorizedUrl" value="/unauthorized" />
<!-- shiro连接约束配置,在这里使用自定义的 从数据库中动态获取资源 -->
<property name="filterChainDefinitionMap" ref="shiroFilterMap" />
</bean>

<!-- 自定义对 shiro的连接约束,结合shiroSecurityFilter实现从数据库中动态获取资源, 默认的连接配置 -->
<bean id="shiroFilterMap" class="system.shiro.ShiroFilterMap">
<property name="filterChainDefinitions">
<value>
/toLogin = anon
/login = anon
/logout = anon
/unauthorized = anon
</value>
</property>
</bean>

<!-- 用户授权信息Cache, 采用EhCache -->
<!-- <bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="/WEB-INF/config/ehcache/ehcache-shiro.xml"
/> </bean> -->

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

</beans>


spring.xml配置

<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">

<mvc:resources mapping="/css/**" location="/css/" />
<mvc:resources mapping="/img/**" location="/img/" />
<mvc:resources mapping="/js/**" location="/js/" />
<mvc:resources mapping="/lib/**" location="/lib/" />

<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<!-- 避免IE执行AJAX时,返回JSON出现下载文件 -->
<bean id="fastJsonHttpMessageConverter"
class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>

<context:component-scan base-package="system" />

<!-- 定义跳转的文件的前后缀 ,视图模式配置 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="system" />
<property name="annotationClass" value="org.springframework.stereotype.Repository">
</property>
</bean>

<!-- 读取数据库属性 -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>

<!-- 配置数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="autoCommitOnClose" value="true" />
</bean>

<!-- mybatis工厂 -->
<bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:mybatis.xml" />
<property name="mapperLocations" value="classpath*:system/**/dao/**/*.xml" />
</bean>

<!-- 配置事务管理器 -->
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>

<!-- 事务通知 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" read-only="true" />
<tx:method name="set*" read-only="true" />
<tx:method name="*" propagation="REQUIRED" rollback-for="Exception" />
</tx:attributes>
</tx:advice>

<!-- aop代理设置 -->
<aop:config proxy-target-class="true">
<aop:pointcut id="txPointcut"
expression="execution(public * system..service..*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"
order="1" />
</aop:config>

<import resource="classpath:shiro.xml" />

</beans>




...全文
234 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
c15852462458 2017-02-23
  • 打赏
  • 举报
回复
看来没有人遇到我的这种问题,帖子结了吧
调试了shiro源码,已经解决了
代码做了如下调整:

url后面加了*号就解决了后缀的问题。
加.do后,url不能与匹配到权限,没有走权限过滤器。走/**=authc的过滤器,此过滤器只是校验是否登入,没有校验权限。
所以只要登入,就可以访问带后缀的了。
c15852462458 2017-02-18
  • 打赏
  • 举报
回复
引用 2 楼 zzhao114 的回复:
你可以在shiro的配置文件里加上这个
<!--所有的请求(除去配置的静态资源请求或请求地址为anon的请求)都要通过登录验证,如果未登录则跳到/login -->
/** = authc


我没在配置文件里加,但在代码里加了,请看这段

首页加载了配置文件里的权限,再加加载了登入用户的权限,最后加了/** = authc
Z. ZHANG 2017-02-18
  • 打赏
  • 举报
回复
你可以在shiro的配置文件里加上这个
<!--所有的请求(除去配置的静态资源请求或请求地址为anon的请求)都要通过登录验证,如果未登录则跳到/login -->
				/** = authc
c15852462458 2017-02-17
  • 打赏
  • 举报
回复

从数据库中读取权限的交给shiro管理的类

package system.shiro;

import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.config.Ini;
import org.apache.shiro.config.Ini.Section;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;

import system.login.dao.LoginDao;
import system.permission.model.Permission;

public class ShiroFilterMap implements FactoryBean<Ini.Section> {

public static int i;

// shiro默认的链接定义 写在xml上的。
private String filterChainDefinitions;

@Autowired
private LoginDao loginDao;

/**
* 通过filterChainDefinitions对默认的链接过滤定义
*
* @param filterChainDefinitions
* 默认的接过滤定义
*/
public void setFilterChainDefinitions(String filterChainDefinitions) {
this.filterChainDefinitions = filterChainDefinitions;
}

@Override
public Section getObject() throws BeansException {
// 加载默认的url
Ini ini = new Ini();
ini.load(filterChainDefinitions);

Ini.Section section = ini.getSection(Ini.DEFAULT_SECTION_NAME);

List<Permission> list = loginDao.getPermissionList();

for (Permission p : list) {
// 访问某一路径,需要对应的权限
String url = p.getUrl();
String code = p.getCode();
if (StringUtils.isNotBlank(url) && StringUtils.isNotBlank(code))
section.put(url, "perms[" + code + "]");
}

section.put("/**", "authc");

return section;
}

@Override
public Class<?> getObjectType() {
return Section.class;
}

@Override
public boolean isSingleton() {
return true;
}

}


自定义的realm类

package system.shiro;

import java.util.List;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import system.constant.Constant;
import system.login.service.LoginService;
import system.user.model.User;

public class MyShiroRealm extends AuthorizingRealm {

@Autowired
private LoginService loginService;

/**
* @category 认证回调函数,登录时调用.获取认证信息
* @param authcToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authcToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
User user = new User();
user.setUsername(token.getUsername());
user = loginService.getUserInfo(user);
if (user != null) {

if (Constant.ENABLED != user.getEnabled()) {
throw new LockedAccountException();
}

SimpleAuthenticationInfo sai = new SimpleAuthenticationInfo(user,
user.getPassword(), getName());
return sai;
} else {
return null;
}
}

/**
* @category 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用. 获取授权信息
* @param principals
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) {
User user = (User) principals.getPrimaryPrincipal();
List<String> list = user.getCodeList();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addStringPermissions(list);
return info;
}

}


登入退出类

package system.login.controller;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import system.login.service.LoginService;

@Controller
@RequestMapping
public class LoginController {

@Autowired
private LoginService loginService;

/**
* @category 跳转登入页面
* @return
*/
@RequestMapping("/toLogin")
public String toLogin() {
Subject subject = SecurityUtils.getSubject();
if (subject.isAuthenticated()) { // 已经登入的用户访问登入页时,跳转到主页
return "redirect:/index";
}
return "/login";
}

/**
* @category 登入操作
* @param model
* @param username
* @param password
* @return
*/
@RequestMapping("/login")
public String login(Model model, String username, String password) {
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username,
password);
String error = "";
try {
subject.login(token);
} catch (UnknownAccountException e) {
error = "用户名或密码错误!";
} catch (IncorrectCredentialsException e) {
error = "用户名或密码错误!";
} catch (LockedAccountException e) {
error = "帐户被锁定,请联系管理员!";
} catch (ExcessiveAttemptsException e) {
error = "登录失败多次,账户锁定10分钟!";
} catch (AuthenticationException e) {
error = "其他错误:" + e.getMessage();
}
if (StringUtils.isNotBlank(error)) {
model.addAttribute("error", error);
return "/login";
}
return "redirect:/index";
}

/**
* @category 登入操作
* @return
*/
@RequestMapping("/logout")
public String logout() {
Subject subject = SecurityUtils.getSubject();
subject.logout();
return "redirect:/toLogin";
}

/**
* @category 跳转主页
* @return
*/
@RequestMapping("/index")
public String index() {
return "/index";
}

/**
* @category 跳转无权限访问的提示页面
* @return
*/
@RequestMapping("/unauthorized")
public String unauthorized() {
return "/error/403";
}

}


权限表结构


如有需要完整代码调试的可联系我270313775@qq.com

81,092

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧