Shiro继承spring
1.需要所有的springmvc.xml的配置
2.需要所有的web.xml的配置
3.需要所有的pom.xml的依赖
4.需要所有的spring.xml的配置
5.jdbc.properties文件
Web.xml配置
<!-- 配置shiro的代理过滤器 filter-name的名字和spring中bean的id一样 -->
<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>
在spring.xml中配置realm
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!-- ref="myDbRealm" 自定义类MyDbRealm加注解@component继承AuthorizingRealm -->
<property name="realm" ref="myDbRealm"/>
</bean>
<!-- 后置处理器(用来注销securityManager) -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
在spring.xml中配置ini
<!-- spring 配置ini bean的id与web.xml中filter-name一样-->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/login.html"/>
<property name="unauthorizedUrl" value="/un.html"/>
<property name="filterChainDefinitions">
<value>
/login.html = anon
/scu.jsp = authc
</value>
</property>
</bean>
加入依赖:
1. <dependency>
2. <groupId>org.apache.shiro</groupId>
3. <artifactId>shiro-spring</artifactId>
4. <version>1.4.0</version>
5. </dependency>
自定义filter实现动态配置url拦截
package cn.et.shiro.conf;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import cn.et.shiro.dao.UserMapper;
import cn.et.shiro.entity.Menu;
@Component
public class MyFilter extends AuthorizationFilter {
@Autowired
private ShiroFilterFactoryBean sffb;
/**
* 匹配指定过滤器规则的url
* @param regex
* @param url
* @return
*/
public static boolean matchUrl(String regex,String url){
regex=regex.replaceAll("/+", "/");
if(regex.equals(url)){
return true;
}
regex=regex.replaceAll("\\.", "\\\\.");
// /login.html /l*.html
regex=regex.replaceAll("\\*", ".*");
// /**/login.html /a/b/login.html
if(regex.indexOf("/.*.*/")>=0){
regex=regex.replaceAll("/\\.\\*\\.\\*/", "((/.*/)+|/)");
}
System.out.println(regex+"----"+url);
return Pattern.matches(regex, url);
}
@Autowired
UserMapper userMapper;
/**
* 测试
* @param args
*/
public static void main(String[] args) {
System.out.println(matchUrl("/**/s*.html","/t/g/login.html"));
}
/**
* isAccessAllowed用于判断当前url的请求是否能验证通过 如果验证失败 调用父类的onAccessDenied决定跳转到登录失败页还是授权失败页面
*/
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
throws Exception {
HttpServletRequest req=(HttpServletRequest)request;
String contextPath=req.getContextPath();
//获取用户访问的资源的路径
String url=req.getRequestURI();
url=url.split(contextPath)[1];
//获取哪些url需要哪些认证
//List<Menu> queryMenu=userMapper.queryMenuByUrl(url);
List<Menu> queryMenu=userMapper.qieryMenu();
if(queryMenu.size()==0){
return false;
}
String urlAuth=null;
for(Menu menu:queryMenu){
if(matchUrl(menu.getMenuUrl(),url)){
//取出权限
urlAuth=menu.getMenuFilter();
}
}
//通数据库没有配置当前url的授权
if(urlAuth==null){
return false;
}
//配置的过滤器是anon 直接放过
if(urlAuth.startsWith("anon")){
return true;
}
//配置的是authc 判断当前用户是否认证通过
Subject subject = getSubject(request, response);
if(urlAuth.startsWith("authc")){
return subject.isAuthenticated();
}
//授权认证 也需要判断是否登录 没有登录返回 登录继续下面的验证
boolean ifAuthc=subject.isAuthenticated();
if(!ifAuthc)
return ifAuthc;
//如果是定义的roles过滤器 获取所有的roles 一般是roles[a,b]
if(urlAuth.startsWith("roles")){
String[] rolesArray=urlAuth.split("roles\\[")[1].split("\\]")[0].split(",");
if (rolesArray == null || rolesArray.length == 0) {
return true;
}
Set<String> roles = CollectionUtils.asSet(rolesArray);
return subject.hasAllRoles(roles);
}
if(urlAuth.startsWith("perms")){
String[] perms=urlAuth.split("perms\\[")[1].split("\\]")[0].split(",");
boolean isPermitted = true;
if (perms != null && perms.length > 0) {
if (perms.length == 1) {
if (!subject.isPermitted(perms[0])) {
isPermitted = false;
}
} else {
if (!subject.isPermittedAll(perms)) {
isPermitted = false;
}
}
}
return isPermitted;
}
return false;
}
}
认证登录实现AuthorizingRealm
package cn.et.shiro.conf;
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.SimpleAccount;
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 org.springframework.stereotype.Component;
import cn.et.shiro.dao.UserMapper;
import cn.et.shiro.entity.UserInfo;
@Component
public class MyDbRealm extends AuthorizingRealm {
@Autowired
UserMapper userMapper;
/**
* 认证
* 将登陆输入的用户名和密码和数据库中的用户名和密码对比 是否相等
* 返回值null表示认证失败 非null认证通过
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//获取从页面传入的token
UsernamePasswordToken upt=(UsernamePasswordToken)token;
//从数据库中查询userinfo对象
UserInfo queryUser=userMapper.queryUser(upt.getUsername());
//如果对象不为空,且密码相等 可以登录
if(queryUser!=null && queryUser.getPassword().equals(new String(upt.getPassword()))){
SimpleAccount sa=new SimpleAccount(upt.getUsername(),upt.getPassword(),"MyDbRealm");
return sa;
}
return null;
}
/**
* 获取当前文件的授权数据
* 将当前用户在数据库的角色和权限 加载到AuthorizationInfo
* 默认在进行授权认证的调用 检查权限调用checkRole checkPerm
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//获取用户名
String userName=principals.getPrimaryPrincipal().toString();
//获取角色
Set<String> roleList=userMapper.queryRoleByName(userName);
//获取权限
Set<String> permsList=userMapper.queryPermsByName(userName);
SimpleAuthorizationInfo sa=new SimpleAuthorizationInfo();
sa.setRoles(roleList);
sa.setStringPermissions(permsList);
return sa;
}
}