shiro框架的使用
Posted super超人
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shiro框架的使用相关的知识,希望对你有一定的参考价值。
基于ssm框架:
1.引入shiro相关jar包:
shiro-core-1.2.3.jar
shiro-ehcache-1.2.3.jar
shiro-quartz-1.2.3.jar
shiro-spring-1.2.3.jar
shiro-web-1.2.3.jar
2.配置applicationContext-shiro.xml(/WEB-INF/conf/applicationContext-shiro.xml):
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" 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"> <description>apache shiro配置</description> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"/> <!-- <property name="loginUrl" value="/index2.jsp"/> <property name="successUrl" value="/main/main.htm"/> <property name="unauthorizedUrl" value="/page/401.htm"/> --> <property name="filterChainDefinitions"> <value> <!-- 静态资源允许访问 --> <!-- /** = anon --> <!-- /app/** = anon /assets/** = anon --> <!-- 登录页允许访问 --> <!-- /user/login.htm = anon --> /test111/loginAdmin.html=anon <!-- 其他资源需要认证 --> /** = authc </value> </property> </bean> <!-- 缓存管理器 使用Ehcache实现 --> <!-- <bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager" p:cacheManagerConfigFile="/WEB-INF/conf/ehcache-shiro.xml"> </bean> --> <!-- 会话DAO --> <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.MemorySessionDAO"/> <!-- 会话管理器 --> <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> <property name="sessionDAO" ref="sessionDAO"/> </bean> <!-- 安全管理器 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realms"> <list> <ref bean="securityRealm"/> </list> </property> <!-- cacheManager,集合spring缓存工厂 --> <!-- <property name="cacheManager" ref="shiroEhcacheManager" /> --> <!-- <property name="sessionManager" ref="sessionManager" /> --> </bean> <!-- Shiro生命周期处理器 --> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> </beans>
3.配置缓存文件:ehcache-shiro.xml(/WEB-INF/conf/ehcache-shiro.xml)
<ehcache updateCheck="false" name="shiroCache"> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="false" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" /> </ehcache>
4.web.xml配置shiro:
<context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/conf/applicationContext.xml /WEB-INF/conf/applicationContext-shiro.xml classpath*:applicationContext.xml </param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- shiro 安全过滤器 --> <filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <async-supported>true</async-supported> <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>
5.java代码:
建立applicationContext-shiro.xml中引用到的类securityRealm:
package com.test.www.web.security; import java.util.HashSet; import java.util.Set; 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.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.springframework.stereotype.Component; import com.test.www.web.entity.user.User; /** * 用户身份验证,授权 Realm 组件 * **/ @Component(value = "securityRealm") public class SecurityRealm extends AuthorizingRealm { /** * 权限检查 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { /*SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); String username = String.valueOf(principals.getPrimaryPrincipal()); System.out.println("ssssssss");*/ //String username = principals.getPrimaryPrincipal().toString() ; SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo() ; /*Set<String> roleName = t_userService.findRoles(username) ; Set<String> permissions = t_userService.findPermissions(username) ;*/ //角色集合 Set<String> roleName = new HashSet<String>(); //权限集合 Set<String> permissions = new HashSet<String>(); roleName.add("admin"); permissions.add("pub:coursecategory"); authorizationInfo.setRoles(roleName); authorizationInfo.setStringPermissions(permissions); return authorizationInfo; } /** * 登录验证 */ @SuppressWarnings("unused") @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { /* String username = String.valueOf(token.getPrincipal()); String password = new String((char[]) token.getCredentials()); System.out.println("aaaaaaa"); SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, password, getName());*/ // int i = 1/0; //获取用户账号 User user = new User() ; user.setUsername("aa"); user.setPassword("bb"); if (user != null){ //将查询到的用户账号和密码存放到 authenticationInfo用于后面的权限判断。第三个参数传入realName。 AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(),"a") ; return authenticationInfo ; }else{ return null ; } } }
PermissionSign常量类:
package com.test.www.web.security; /** * 权限标识配置类, <br> * 与 permission 权限表 中的 permission_sign 字段 相对应 <br> * 使用: * * <pre> * @RequiresPermissions(value = PermissionConfig.USER_CREATE) * public String create() { * return "拥有user:create权限,能访问"; * } * </pre> * **/ public class PermissionSign { //课程类别表权限 public static final String PUB_COURSECATEGORY = "pub:coursecategory"; }
TestController类:
package com.test.www.web.controller; import java.util.HashMap; import java.util.Map; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.subject.Subject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.test.www.test.exception.TestException; import com.test.www.util.PrimaryKeyGenerator; import com.test.www.web.entity.user.User; import com.test.www.web.security.PermissionSign; import com.test.www.web.service.user.UserService; @RequestMapping("/test111") @Controller public class TestController { private final static Logger logger = LoggerFactory.getLogger(TestException.class); @Resource private UserService userService; /** * 注意: * 1.如果不是ajax提交表单,权限认证异常跳转到web.xml中配置的路径; * 2.如果是ajax请求,权限认证异常不是按照web.xml跳转 */ @RequestMapping("/add") @ResponseBody @RequiresPermissions(value=PermissionSign.PUB_COURSECATEGORY) //PUB_TRAININGTYPE PUB_COURSECATEGORY 增加权限控制 public Map<String,Object> saveUser( User user, ModelMap map, HttpServletResponse response, HttpServletRequest request ){ Map<String,Object> resultMap = new HashMap<String,Object>(); try{ user.setId(PrimaryKeyGenerator.getLongKey()); int resultCount = userService.insertUser(user); if(resultCount>0){ resultMap.put("msg", "success"); resultMap.put("user", user); } }catch(Exception e){ e.printStackTrace(); resultMap.put("msg", "failure"); } return resultMap; } @RequestMapping("/loginAdmin") public String login(){ User user = new User(); user.setUsername("aa"); user.setPassword("bb"); Subject subject = SecurityUtils.getSubject() ; UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),user.getPassword()) ; logger.info("登录成功1"); logger.info("--info--"); logger.debug("--debug--"); logger.error("-error-"); logger.warn("--warn--"); System.out.println(System.getProperty("test2.root")); System.out.println(System.getProperty("Academic.root")); try { subject.login(token); return "index2" ; }catch (Exception e){ //这里将异常打印关闭是因为如果登录失败的话会自动抛异常 // e.printStackTrace(); return "index" ; } } }
说明:
1.登录验证:
login()方法进行登录验证,subject.login(token);是验证核心,执行到这一步会进入SecurityRealm执行doGetAuthenticationInfo进行登录验证。
2.采用注解控制权限:
执行saveUser方法操作,由于方法上面添加了权限注解@RequiresPermissions(value=PermissionSign.PUB_COURSECATEGORY),
执行该操作会先进入到SecurityRealm的doGetAuthorizationInfo方法中获取用户的角色、权限并进行权限检查,只有拥有该权限的用户才能执行该操作,没有该权限则会转向未授权页面。
去掉该注解,则不进行权限检查,不执行SecurityRealm的doGetAuthorizationInfo方法,所有用户都能执行该操作。
操作结果如图所示:
1.用户名密码都正确,用户拥有权限pub:coursecategory:
2.用户名密码正确,用户没有操作权限:
将doGetAuthorizationInfo中的permissions.add("pub:coursecategory");改为permissions.add("pub:coursecategory1");
操作结果如图所示:
其他情况可自行测试。
以上是关于shiro框架的使用的主要内容,如果未能解决你的问题,请参考以下文章