天天看点

ssm整合shiro

      开始整合前呢,得先搭建maven,spring,spring mvc,mybatis框架,这种教程网上很多也很详细,自己手动搜一下,实在没有适合自己的,下面留言,我帮你找哈。

      配置好的项目结构大概如下,但有的人喜欢名字不一样,或者把Mapper.xml放到其他地方也可以,注意在配置文件修改路径就好。

ssm整合shiro

整合

第一步:

在pom.xml中引入shiro的依赖及相关jar包

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-all</artifactId>
    <version>1.3.2</version>
</dependency>
           

或者添加jar包

ssm整合shiro

第二步:

在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相同,则验证通过,否则不会执行,会抛出异常。

ssm整合shiro

在下图中第一个方框数据库中查出权限,在第二个框处添加到集合中,第三个框把授权信息填充到simpleAuthorizationInfo对象中进行判断。

ssm整合shiro

下图在页面上进行权限管理,是否显示中间内容

ssm整合shiro

在shiro配置文件中,通过配置路径来管理登录验证,= 前面的数据要以 / 开头

ssm整合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');
           

继续阅读