ruijiege

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

1.在pom添加集成导入

 <!-- shiro的支持包 -->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-all</artifactId>
      <version>1.4.0</version>
      <type>pom</type>
    </dependency>
    <!-- shiro与Spring的集成包 -->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-spring</artifactId>
      <version>1.4.0</version>
    </dependency>

 

 2.在WEB-INF/web.xml中添加一个过滤器

 <!-- Shiro Filter is defined in the spring application context: -->
  <!--配置一个DelegatingFilterProxy这是一个下放权限,把请求让给
  <filter-name>shiroFilter</filter-name>通过shiroFilter这个名称去
  -->
  <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>

 

2.写一个配置文件

自定义一个applicationContext-shiro.xml

<?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">
    <!--  DefaultSecurityManager securityManager = new DefaultSecurityManager();-->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <!--引入到securityManager的realm-->
        <property name="realm" ref="myRealm"/>
    </bean>
    <!--配置我自己的realm-->
    <bean id="myRealm" class="cn.jiedada.aisell.web.controller.shiro.MyRealm">
        <!--name无关紧要-->
        <property name="name" value="myRealm"/>
        <!---->
        <property name="credentialsMatcher">
            <!--  设置密码解析器
             HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
                     hashedCredentialsMatcher.setHashAlgorithmName("MD5");
                    hashedCredentialsMatcher.setHashIterations(10); -->
            <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                <property name="hashAlgorithmName" value="MD5"/>
                <property name="hashIterations" value="10"/>
            </bean>
        </property>
    </bean>
    <!--下放请求到当前页面-->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
        <!--当我们没登陆的是否跳到当前页面-->
        <property name="loginUrl" value="/s/login.jsp"/>
        <!--登陆成功调到该页面-->
        <property name="successUrl" value="/s/index.jsp"/>
        <!--有权限的,如果没有则跳转到该页面-->
        <property name="unauthorizedUrl" value="/s/unauthorized.jsp"/>
        <!--/s/login = anon放行
         /s/permission.jsp = perms[user:index]需要user:index权限才能访问
                /** = authc -->
<!--        <property name="filterChainDefinitions">
            <value>
                /s/login = anon
                /login = anon
                /s/permission.jsp = perms[user:index]
                /** = authc
            </value>
        </property>-->
        <property name="filterChainDefinitionMap" ref="filterChainDefinitionMap"></property>
    </bean>
    <bean id="filterChainDefinitionMap" factory-bean="shiroFilterMapFactory" factory-method="createMap" />
    <!--配置返回shiro权限拦截的bean-->
    <bean id="shiroFilterMapFactory" class="cn.jiedada.aisell.web.controller.shiro.ShiroFilterMapFactory"/>

</beans>
View Code

 

3.要把该配置写入applicationContext.xml中

<!--把applicationContext-shiro.xml放在spring中运行-->
    <import resource="classpath:applicationContext-shiro.xml"/>

就完成了最基础的配置

这里是MyRealm

package cn.jiedada.aisell.web.controller.shiro;

import org.apache.shiro.authc.*;
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.apache.shiro.util.ByteSource;

import java.util.HashSet;
import java.util.Set;

public class MyRealm extends AuthorizingRealm {
    /*授权
    * */
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //设置冲数据库中传来的角色
        simpleAuthorizationInfo.setRoles(this.getRoles());
        //设置冲数据库中传来的权限
        simpleAuthorizationInfo.setStringPermissions(getPerms());
        return simpleAuthorizationInfo;
    }
    private Set getRoles(){
        Set set = new HashSet();
        set.add("admin");
        return  set;
    }
    private Set getPerms(){
        Set set = new HashSet();
        set.add("employee:index");
        return  set;
    }
    /*身份验证
    返回值null为用户名错误
    * */
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //获得token序列
        UsernamePasswordToken token=(UsernamePasswordToken)authenticationToken;
        //获得用户名
        String username = token.getUsername();
        //去数据库查询密码
        String pwd = getUsers(username);
        if(pwd!=null){
            //验证密码,传入三个参数
            //设置盐
            ByteSource byteSource = ByteSource.Util.bytes("jiedada");
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username,pwd,byteSource,"myshiro");
            return simpleAuthenticationInfo;
        }
        return null;
    }
    private String getUsers(String username){
        if("adimn".equals(username)){
            return "2a7e4163f7f9f316d03c3f384eeb301b";
        }
        return null;
    }
}
View Code

 这个比较好一点

package cn.jiedada.crm.web.shiro;

import cn.jiedada.crm.domain.Employee;
import cn.jiedada.crm.domain.Permission;
import cn.jiedada.crm.service.IEmployeeService;
import cn.jiedada.crm.service.IPermissionService;
import org.apache.shiro.authc.*;
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.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.Set;

public class MyRealm extends AuthorizingRealm {
    @Autowired
    private IEmployeeService employeeService;
    @Autowired
    private IPermissionService permissionService;

    /*授权
     * */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //设置冲数据库中传来的角色
        //simpleAuthorizationInfo.setRoles(this.getRoles());
        //设置冲数据库中传来的权限
        Set<String> pers = permissionService.findLogSn();
        simpleAuthorizationInfo.setStringPermissions(pers);
        return simpleAuthorizationInfo;
    }
    /*省份验证*/
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
       //获得token
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        //获得用户名
        String username = token.getUsername();
        //在数据库中查找获得数据
        Employee employee = employeeService.findEmployeeByUsername(username);
        //判断是否为空
        if(employee==null){
            throw new UnknownAccountException(username);
        }
        //设置principal
        Object principal = employee;
        //获得数据库的密码
        Object hashedCredentials = employee.getPassword();
        ByteSource credentialsSalt = ByteSource.Util.bytes(MD5Util.SALT);
        String realmName = getName();
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal,hashedCredentials,credentialsSalt,realmName);
        return info;
    }

}
View Code

 

这里是ShiroFilterMapFactory

package cn.jiedada.aisell.web.controller.shiro;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 用于返回下面的这些值(这里的值是有顺序的:LinkedHashMap)
 *   <value>
         /login = anon
         /s/permission.jsp = perms[user:index]
         /** = authc
    </value>
 */
public class ShiroFilterMapFactory {

    public Map<String,String> createMap(){
        Map<String,String> map = new LinkedHashMap<>();
        //anon:需要放行的路径
        map.put("/login","anon");
        //perms:权限拦截
        map.put("/s/permission.jsp","perms[employee:index]");
        //authc:拦截
        map.put("/**","authc");
        return map;
    }
}
View Code

 因为会发送Ajax请求所以我们需要判断是否为ajax判断

AisellPermissionsAuthorizationFilter

package cn.jiedada.crm.web.shiro;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.StringUtils;
import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter;
import org.apache.shiro.web.util.WebUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 写一个自己的Shiro来判断出我们需要的东西处理Ajax权限
 */
public class AisellPermissionsAuthorizationFilter extends PermissionsAuthorizationFilter {

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
        Subject subject = this.getSubject(request, response);
        //判断用户是否登陆
        if (subject.getPrincipal() == null) {
            this.saveRequestAndRedirectToLogin(request, response);
        } else {
            //只用通过HttpServletRequest才能获得请求头中的数据才能判断
            HttpServletRequest httpRequest = (HttpServletRequest) request;
            HttpServletResponse httpResponse=(HttpServletResponse)response;
            //查看是否是AjAX请求
            String xRequested = httpRequest.getHeader("X-Requested-With");
            if(xRequested!=null&&"XMLHttpRequest".equals(xRequested)){
                //传入前需要在请求头中传入响应,让他知道我们返回的数据是AJAX请求
                httpResponse.setContentType("text/json; charset=UTF-8");
                //带回AJAX请求,把数据作为流传回去这里需要传出标准的json数据格式
                httpResponse.getWriter().print( "{\"success\":false,\"msg\":\"没有权限\"}");

            }else {
                String unauthorizedUrl = this.getUnauthorizedUrl();
                if (StringUtils.hasText(unauthorizedUrl)) {
                    WebUtils.issueRedirect(request, response, unauthorizedUrl);
                } else {
                    WebUtils.toHttp(response).sendError(401);
                }
            }
        }
        return false;
    }
}
View Code

 

posted on 2019-10-18 08:44  哦哟这个怎么搞  阅读(293)  评论(0编辑  收藏  举报