实际开发项目中shiro经常与spring集成使用,该文章就来介绍下sping集成shiro完成权限验证的操作。
1、引入shiro相关jar包
加入shiro的jar包,此处使用版本为1.4.0,spring的jar包就忽略了(当 大家有spring基础)
<!-- Shiro权限管理 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-quartz</artifactId>
<version>1.4.0</version>
</dependency>
2、在web.xml中加入shiro的过滤器
<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>
<init-param>
<param-name>targetBeanName</param-name>
<param-value>shiroFilter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3、编写shiro的登录和权限认证类Realm
/**
* 权限认证,验证授权信息,主要设置用户的角色和权限信息
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//1.获取登录用户信息
HUser user = (HUser) principalCollection.getPrimaryPrincipal();
//2.查询用户的权限信息
List<HPermission> permissionList =
permissionService.findPermissonByUser(user.getId());
// 创建权限信息对象
SimpleAuthorizationInfo authorizationInfo =
new SimpleAuthorizationInfo();
Set<String> permissionSet=new HashSet<>();
for (HPermission hPermission : permissionList) {
permissionSet.add(hPermission.getPercode());
}
//设置权限信息(权限编码)
authorizationInfo.setStringPermissions(permissionSet);
List<HRole> roleList = roleService.findRolesByUser(user.getId());
Set<String>roleSet=new HashSet<>();
for (HRole hRole : roleList) {
roleSet.add(hRole.getRolecode());
}
//设置角色信息(角色编码)
authorizationInfo.setRoles(roleSet);
return authorizationInfo;
}
/**
* 身份认证,登录时判断用户身份信息
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//1、authenticationToken 保存了用户登录信息,获取前台登录传递的用户名
String name = (String) authenticationToken.getPrincipal();
//2、根据用户名查询用户信息
HUser user = userService.findUserByName(name);
//返回null则验证不通过
if(user==null) {
return null;
}
//身份认证信息对象
//第一个参数为需要保存到session中的对象
//第二个参数为数据库中存储的密码
//第三个参数为盐值
//第四个参数为自定义的realm的名字
SimpleAuthenticationInfo simpleAuthenticationInfo=
new SimpleAuthenticationInfo(user,user.getPassword()
,new SimpleByteSource(user.getCreatetime().getTime()+"")
,getName());
return simpleAuthenticationInfo;
}
4、与spring整合
4.1 配置applicationContext-shrio.xml配置文件,用以配置shiro的信息
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--配置sessionManager-->
<bean id="sessionManager"
class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<!--设置session超时时间-->
<property name="globalSessionTimeout" value="9000000"></property>
<!--设置删除无效session-->
<property name="deleteInvalidSessions" value="true"/>
</bean>
<!--设置加密方式-->
<bean id="credentialsMatcher"
class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!--设置加密算法-->
<property name="hashAlgorithmName" value="md5"/>
<!--设置加密次数-->
<property name="hashIterations" value="1"/>
</bean>
<!--配置Realm-->
<bean id="myRealm" class="com.seecen.ssm.shiro.MyRealm">
<!--将加密方式注入-->
<property name="credentialsMatcher" ref="credentialsMatcher"/>
</bean>
<!--配置安全管理器-->
<bean id="securityManager"
class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!--注入验证类-->
<property name="realm" ref="myRealm"/>
<!--注入sessionManager-->
<property name="sessionManager" ref="sessionManager"/>
</bean>
<!--配置shiro的过滤器-->
<bean id="shiroFilter"
class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!--注入安全管理器-->
<property name="securityManager" ref="securityManager"/>
<!--配置登录页面地址,当用户未登录时会跳转到该地址-->
<property name="loginUrl" value="/login.jsp"></property>
<!--登录成功地址-->
<property name="successUrl" value="/index.jsp"></property>
<!--配合过滤规则-->
<property name="filterChainDefinitions">
<value>
/js/** =anon
/login.jsp =anon
/plugins/** =anon
/login =anon
/register.jsp =anon
/register =anon
/** =authc
</value>
</property>
</bean>
</beans>
@RequestMapping("/register")
public String register(HUser user){
//设置创建时间
user.setCreatetime(new Date());
//将用户密码MD5加密
SimpleHash md5 = new SimpleHash(
"MD5"//加密方法
,user.getPassword()//需要加密的数据
,user.getCreatetime().getTime()+""//盐值
,2);//加密次数
//将加密后的密码设置进user对象
user.setPassword(String.valueOf(md5));
userService.insert(user);
return "redirect:/toLogin";
}
@RequestMapping("login")
public String login(HUser user){
//获取登录用户Subject
Subject subject = SecurityUtils.getSubject();
//封装token
UsernamePasswordToken token=
new UsernamePasswordToken(user.getName(),user.getPassword());
try {
//执行登录验证,会调用自定义realm进行验证。
subject.login(token);
}catch (AuthenticationException e){
//如果抛出异常,则认证失败,跳转到登录页面
return "login";
}
//没抛异常则认证通过,跳转到首页
return "redirect:/index";
}
4.2 在springmvc配置文件中配置shiro
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--设置返回json格式数据时,日期格式 ,当某些需要特殊处理,不按此方式来时,
在get方法上使用@JsonFormat(pattern="yyyy-MM-dd",timezone = "GMT+8")-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter" />
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" >
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<!-- 设置全局返回JSON到前端时日期格式化 -->
<constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss"/>
</bean>
</property>
</bean>
</property>
</bean>
</list>
</property>
</bean>
<!--aop注解-->
<aop:aspectj-autoproxy/>
<!--<aop:aspectj-autoproxy proxy-target-class="true" />-->
<!--开启注解-->
<mvc:annotation-driven/>
<!--配置控制层扫描包-->
<context:component-scan base-package="com.seecen.ssm.controller,com.seecen.ssm.aop"/>
<!--配置静态资源-->
<mvc:default-servlet-handler />
<!--设置开启shiro注解-->
<aop:config proxy-target-class="true"/>
<bean
class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"></property>
</bean>
<!--
springmvc简单异常处理器,配置异常信息,实现全局异常处理
也可以自定义全局异常处理类 implements HandlerExceptionResolver
@ControllerAdvice+ @ ExceptionHandler等
-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!--配置异常信息跳转规则-->
<property name="exceptionMappings">
<props>
<!--配置异常对应的操作-->
<prop key="org.apache.shiro.authz.UnauthorizedException">
/refuse.jsp
</prop>
</props>
</property>
</bean>
</beans>
网友评论