开始整合前呢,得先搭建maven,spring,spring mvc,mybatis框架,这种教程网上很多也很详细,自己手动搜一下,实在没有适合自己的,下面留言,我帮你找哈。
配置好的项目结构大概如下,但有的人喜欢名字不一样,或者把Mapper.xml放到其他地方也可以,注意在配置文件修改路径就好。
整合
第一步:
在pom.xml中引入shiro的依赖及相关jar包
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.3.2</version>
</dependency>
或者添加jar包
第二步:
在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>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
位置放置在所有filter的最上面。
第三步:
编写自定义Realm
package com.jhq.kiven.shiro;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Resource;
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.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import com.google.gson.Gson;
import com.jhq.kiven.entity.LoginEntity;
import com.jhq.kiven.service.LoginService;
public class ShiroDbRealm extends AuthorizingRealm {
private static final String ALGORITHM = "MD5";
@Resource
private LoginService loginService;
public ShiroDbRealm() {
super();
}
/**
* 验证登陆
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authcToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
System.out.println(token.getUsername());
LoginEntity user =loginService.getTUser(token.getUsername());
System.out.println("user:"+user);
// CipherUtil cipher = new CipherUtil();//MD5加密
if (user != null) {
// return new SimpleAuthenticationInfo(user.getName(), cipher.generatePassword(user.getPassword()), getName());
return new SimpleAuthenticationInfo(user.getAccount(), user.getPassword(), getName());
}else{
throw new AuthenticationException();
}
}
/**
* 登陆成功之后,进行角色和权限验证
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
Set<String> permissions = new HashSet<String>(); //权限集合
Set<String> roles = new HashSet<String>(); //角色集合
// 从 principals获取主身份信息
// 将getPrimaryPrincipal方法返回值转为真实身份类型(在上边的doGetAuthenticationInfo认证通过填充到SimpleAuthenticationInfo中身份类型),
String activeUser = (String)principals.getPrimaryPrincipal();
System.out.println("权限principals:"+new Gson().toJson(activeUser));
// 根据身份信息获取权限信息
// 从数据库获取到权限数据
LoginEntity adminRoles = loginService.getTUser(activeUser);
System.out.println("adminRoles:"+new Gson().toJson(adminRoles));
// 单独定一个角色集合对象
if (adminRoles != null) {
System.out.println("权限数据库:"+adminRoles.getAuthority());
//添加角色
roles.add(adminRoles.getAuthority());
}
//添加权限
permissions.add("/logi");
// 查到权限数据,返回授权信息(要包括 上边的permissions)
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
// 将上边查询到授权信息填充到simpleAuthorizationInfo对象中
simpleAuthorizationInfo.setRoles(roles);
simpleAuthorizationInfo.addStringPermissions(permissions);
System.out.println("角色权限:"+new Gson().toJson(simpleAuthorizationInfo.getRoles()));
return simpleAuthorizationInfo;
}
/**
* 清除所有用户授权信息缓存.
*/
public void clearCachedAuthorizationInfo(String principal) {
SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
clearCachedAuthorizationInfo(principals);
}
/**
* 清除所有用户授权信息缓存.
*/
public void clearAllCachedAuthorizationInfo() {
Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
if (cache != null) {
for (Object key : cache.keys()) {
cache.remove(key);
}
}
}
}
doGetAuthenticationInfo方法是登录验证账户
doGetAuthorizationInfo方法是登陆后的权限控制
验证账号登录时,返回new SimpleAuthenticationInfo参数可以加密
权限控制中有角色权限和访问权限之分(
simpleAuthorizationInfo.setRoles(roles);//角色权限
simpleAuthorizationInfo.addStringPermissions(permissions); //访问权限
)可以单独使用,也可以一起使用。
第四步:
编写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-3.0.xsd"
default-lazy-init="true">
<description>Shiro Configuration</description>
<!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="shiroDbRealm" />
<property name="cacheManager" ref="cacheManager" />
</bean>
<!-- 項目自定义的Realm -->
<bean id="shiroDbRealm" class="com.jhq.kiven.shiro.ShiroDbRealm">
<property name="cacheManager" ref="cacheManager" />
</bean>
<!-- Shiro Filter -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<!-- 用户登录地址 -->
<property name="loginUrl" value="/login" />
<!-- 登录成功 -->
<property name="successUrl" value="/success.jsp" />
<!-- 未授权的失败页 -->
<property name="unauthorizedUrl" value="/error.jsp" />
<property name="filterChainDefinitions">
<value>
<!-- 设置访问用户list页面需要授权操作 -->
/index.jsp = anon
/login = anon
/** = authc
</value>
</property>
</bean>
<!-- 给予shior的内存缓存系统 -->
<bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager"/>
<!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
</beans>
其中要注意的是,自定义Realm的id必须和web.xml里面的filter-name一样,Realm的class地址要准确无误。
第五:
在访问控制层添加代码
@Controller
@RequestMapping("/")
public class LoginController {
@Resource
private LoginService loginService;
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String showUserInfo(HttpServletRequest request,HttpSession session){
String result = "/login";
String account = request.getParameter("account");
String password = request.getParameter("password");
UsernamePasswordToken token = new UsernamePasswordToken(account, password);
Subject currentUser = SecurityUtils.getSubject();
try {
System.out.println("----------------------------");
if (!currentUser.isAuthenticated()){//使用shiro来验证
token.setRememberMe(true); //记住我
currentUser.login(token);//验证角色和权限
}
System.out.println("result: " + result);
result = "/success";//验证成功
} catch (Exception e) {
result = "/login";//验证失败
}
return result;
}
}
第六:
在spring mvc配置文件中添加如下配置
<bean
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="true" />
</bean>
<bean
class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager" />
</bean>
有些demo里面会把它添加到shiro配置文件中,但是我发现会造成注解模式下的权限验证失效。也有人将失效是因为要把注解放到service方法中,而不是controller中,但我试了还是没效果,最终放到spring mvc里面成功了,具体原因还不清楚。
第七:
将shiro配置文件加载到项目中
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml,classpath:spring-mybatis.xml,classpath:spring-shiro.xml</param-value>
</context-param>
在web.xml里边加载shiro配置文件
好了,启动程序,看看能不能正常启动,如果报错,百度一下错误,问题应该不大。
在跳转页面的controller中,我添加了注解角色权限验证,如果bbb等于自定义ShiroDbRealm中的doGetAuthorizationInfo方法里面从数据库获取到的roles相同,则验证通过,否则不会执行,会抛出异常。
在下图中第一个方框数据库中查出权限,在第二个框处添加到集合中,第三个框把授权信息填充到simpleAuthorizationInfo对象中进行判断。
下图在页面上进行权限管理,是否显示中间内容
在shiro配置文件中,通过配置路径来管理登录验证,= 前面的数据要以 / 开头
具体如下
/admins/**=anon # 表示该 uri 可以匿名访问
/admins/**=auth # 表示该 uri 需要认证才能访问
/admins/**=authcBasic # 表示该 uri 需要 httpBasic 认证
/admins/**=perms[user:add:*] # 表示该 uri 需要认证用户拥有 user:add:* 权限才能访问
/admins/**=port[8081] # 表示该 uri 需要使用 8081 端口
/admins/**=rest[user] # 相当于 /admins/**=perms[user:method],其中,method 表示 get、post、delete 等
/admins/**=roles[admin] # 表示该 uri 需要认证用户拥有 admin 角色才能访问
/admins/**=ssl # 表示该 uri 需要使用 https 协议
/admins/**=user # 表示该 uri 需要认证或通过记住我认证才能访问
/logout=logout # 表示注销,可以当作固定配置
anon,authcBasic,auchc,user 是认证过滤器。
perms,roles,ssl,rest,port 是授权过滤器。
这是项目地址 https://download.csdn.net/download/qq_35776126/10604692
运行时请修改数据库配置为你自己的配置
检表语句
DROP TABLE IF EXISTS `workattendance`;
CREATE TABLE `workattendance` (
`id` bigint(12) NOT NULL AUTO_INCREMENT,
`name` varchar(24) DEFAULT NULL,
`email` varchar(32) DEFAULT NULL,
`account` varchar(32) DEFAULT NULL,
`password` varchar(64) DEFAULT NULL,
`sign` bigint(2) DEFAULT NULL,
`authority` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;
insert into `workattendance`(`id`,`name`,`email`,`account`,`password`,`sign`,`authority`) values (1,'kiven','[email protected]','admin','123',1,'bbb');