1. 程式人生 > 其它 >shiro怎麼讓控制器匿名訪問_Java高階框架 - Shiro學習(02) Day17

shiro怎麼讓控制器匿名訪問_Java高階框架 - Shiro學習(02) Day17

技術標籤:shiro怎麼讓控制器匿名訪問

1. Shiro整合SpringMVC基於XML


1.1. 說明

上面的知識,我們已經瞭解Shiro的許可權授權、許可權校驗、Md5的加密密碼的配置。

但是,我們的需求將Shiro框架用到Web專案。

所以,我們需要使用Shiro整合SpringMVC使用!!!

1.2. 整合步驟說明

1. 配置SpringMVC框架

2. 配置Shiro框架

3. 整合SpringMVC與Shiro

1.3. 整合步驟

1.3.1. 第一部分:SpringMVC框架的配置

1.3.1.1. 步驟說明

1. 匯入依賴的Jar包

2. 構建一個請求頁面

3. 建立業務控制器

4. 配置web.xml的核心控制器

5. 建立配置檔案

6. 構建一個返回頁面

1.3.1.2. 第一步:匯入依賴的Jar包

48fad0ba3371d9029eec7f0b89c43a5e.png

1.3.1.3. 第二步:構建一個請求頁面

<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
 <a href="${pageContext.request.contextPath }/admin/addAdmin">addAdmin</a>
</body>
</html>

1.3.1.4. 第三步:建立業務控制器

package cn.gzsxt.controller;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.annotation.SessionScope;
 
@Controller
@SessionScope
@RequestMapping(value="admin")
public class AdminController {
 
 @RequestMapping(value="/addAdmin")
 public String addAdmin(){
        System.out.println("=增加管理員=");
 return "/index.jsp";
    }
 
}
 

1.3.1.5. 第四步:配置web.xml的核心控制器

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://xmlns.jcp.org/xml/ns/javaee"
 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
 id="WebApp_ID" version="3.1">
 <display-name>shiro-demo-08-springmvc</display-name>
 
 <!-- 配置核心控制器。攔截器所有的請求 -->
 <servlet>
 <servlet-name>dispatcherServlet</servlet-name>
 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
 <!-- 指定配置檔案的路徑 -->
 <init-param>
 <param-name>contextConfigLocation</param-name>
 <param-value>classpath:spring-*.xml</param-value>
 </init-param>
 <!-- 配置啟動的時候就建立物件 -->
 <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
 <servlet-name>dispatcherServlet</servlet-name>
 <url-pattern>/</url-pattern>
 </servlet-mapping>
 
 <welcome-file-list>
 <welcome-file>index.jsp</welcome-file>
 </welcome-file-list>
</web-app>

1.3.1.6. 第五步:建立配置檔案

--SpringMVC配置檔案,spring-mvc.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"
 xmlns:mvc="http://www.springframework.org/schema/mvc"
 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-4.3.xsd">
 
 <!-- 啟動預設註解支援 -->
 <mvc:annotation-driven />
 <!-- 放開靜態資源訪問 -->
 <mvc:default-servlet-handler/>
 
</beans>
 

--Spring容器配置檔案,spring-context.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"
 xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
 
 <!-- 掃描元件配置 -->
 <context:component-scan base-package="cn.gzsxt" />
</beans>
 

1.3.2. 第二部分:Shiro框架的配置

1.3.2.1. 配置步驟說明

1. 匯入依賴的Jar包

2. 建立Shiro.ini配置檔案

3. 建立一個入口測試類

4. 建立一個Realm

1.3.2.2. 第一步:匯入依賴的Jar包

c11e082664a3daa0f84bd587daba7d11.png

1.3.2.3. 第二步:建立Shiro.ini配置檔案

[users]
 admin = 123456,adminRole
[roles]
  adminRole = admin:list,admin:add,admin:delete,admin:edit  

1.3.2.4. 第三步:建立一個入口測試類

package cn.gzsxt.shiro.test;
 
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
 
public class ShiroTest {
 
 
 public static void main(String[] args) {
 //第一步:載入ini配置檔案,獲得SecurityManagerFactory物件
        IniSecurityManagerFactory factory=new IniSecurityManagerFactory("classpath:shiro.ini");
 //第二步:獲得SecurityManager物件
        SecurityManager securityManager = factory.createInstance();
 //第三步:獲得Subject身份物件
        SecurityUtils.setSecurityManager(securityManager);
        Subject subject = SecurityUtils.getSubject();
 
 //第四步:構建一個身份資訊物件(Token)
        UsernamePasswordToken token=new UsernamePasswordToken("admin","123456");
 
 //第五步:login操作。校驗許可權
        Subject resultSubject = securityManager.login(subject, token);
 
 //第六步:校驗是否成功
 boolean isAuth= resultSubject.isAuthenticated();
        System.out.println(isAuth);
 
    }
 
}
 

1.3.2.5. 第四步:建立一個Realm

--修改配置檔案

#[users]
#  admin = 123456,adminRole
#[roles]
#  adminRole = admin:list,admin:add,admin:delete,admin:edit  
 
[main]
  myRealm = cn.gzsxt.realm.MyRealm
  securityManager.realms=$myRealm

--MyRealm類

package cn.gzsxt.realm;
 
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.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
 
public class MyRealm extends AuthorizingRealm {
 
 @Override
 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("=許可權校驗=");
 try {
 if (token.getPrincipal().equals("admin")) {
                SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(token.getPrincipal(), "123456",
 this.getName());
 return info;
            }
        } catch (Exception e) {
 e.printStackTrace();
        }
 
 return null;
    }
 
 @Override
 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
 SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
 info.addRole("role_admin");
 info.addStringPermission("user:add");
 info.addStringPermission("user:list");
 //info.addStringPermission("user:edit");
 
 return info;
 
    }
 
}
 

1.3.2.6. 第五步:測試結果

--執行ShiroTest測試類,結果為:

606dcdc6d22f73138b54c7baa649d372.png

1.3.3. 第三部分:SpringMVC整合Shiro

1.3.3.1. 說明

1. 許可權控制是對誰的控制?,就是對url訪問許可權的控制。

2. Filter的攔截請求優先級別高於Servlet。而Shiro是使用Filter攔截的,SpringMVC是使用Servlet攔截請求的。那麼我們如何讓Shiro交給SpringMVC代理呢?

答:Spring提供了一個Filter代理類,可以讓Spring容器代理Filter的操作,DelegatingFilterProxy。實現了在過濾裡面可以呼叫Spring容器的物件,把我們原來配置在web.xml的過濾器配置在Spring配置檔案裡面。

1.3.3.2. Shiro提供的過濾器說明

在org.apache.shiro.web.filter.mgt.DefaultFilter列舉裡面定義可以使用的過濾器以及對於的列舉值

9ef9bc4a79a4d2172c79bf6503fc7529.png
anon : 匿名過濾器,該過濾器的作用就是用於配置不需要授權就可以直接訪問的路徑。
authc: 校驗過濾器,該過濾器的作用就是用於必須經過校驗才可以訪問的路徑(url)
logout: 登出過濾器, 該過濾器的作用就是用於登出退出登入。
perms:許可權驗證過濾器,用於許可權驗證的

1.3.3.3. 配置步驟說明

1. 在web.xml配置過濾器代理類DelegatingFilterProxy,讓Filter交個Spring容器代理

2. 建立一個spring-shiro.xml配置檔案

1.3.3.4. 第一步:配置web.xml

 <filter>
 <filter-name>securityFilterBean</filter-name>
 <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
 <!-- 將生命週期交給Spring代理 -->
 <init-param>
 <param-name>targetFilterLifecycle</param-name>
 <param-value>true</param-value>
 </init-param>
 </filter>
 <filter-mapping>
 <filter-name>securityFilterBean</filter-name>
 <url-pattern>/*</url-pattern>
 </filter-mapping>

1.3.3.5. 第二步:建立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.xsd">
 
 <!-- 配置攔截器呼叫的物件 注意事項:bean的名字必須要和web.xml的DelegatingFilterProxy的過濾的name屬性一一對應。 -->
 <bean name="securityFilterBean" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
 <!-- 指定跳轉到校驗不成功的路徑 ,不指定會跳轉上一次訪問選單頁面 -->
 <!-- <property name="unauthorizedUrl" value="/undo"></property> -->
 <!-- 指定依賴的securityManager物件 -->
 <property name="securityManager" ref="securityManager"></property>
 <!-- 指定 登入請求的路徑 -->
 <property name="loginUrl" value="/admin/loginAdmin"></property>
 <!-- 登入成功跳轉的路徑 -->
 <property name="successUrl" value="/index"></property>
 <!-- 用於指定執行的過濾器鏈 ,配置多個過濾器連線對的url -->
 <property name="filterChainDefinitions">
 <value>
 <!-- 指定url與過濾器的關係 -->
 <!-- 所有的路徑都要攔截 -->
                /admin/toLogin = anon
                /** = authc
 </value>
 </property>
 
 </bean>
 
 <!-- 2.指定securityManager的物件 -->
 <bean name="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
 
 <property name="realm" ref="myRealm" />
 
 </bean>
 
 <!-- 3.建立一個Realm物件 -->
 <bean name="myRealm" class="cn.gzsxt.realm.MyRealm"></bean>
 
 <!-- 4.Spring容器對shiro生命週期的管理 ,基於註解許可權攔截需要配置-->
 <bean name="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"></bean>
 <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>
 
</beans>

1.3.3.6. 第三步:許可權控制器標籤的使用

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
  主頁  <a href="${pageContext.request.contextPath }/logout">退出</a><br/>
 <shiro:hasPermission name="user:list">
 <!-- 如果有user:list許可權才顯示  使用者列表 -->
 <a href="#"> 使用者列表</a><br/>
 </shiro:hasPermission>
 <shiro:hasPermission name="user:add">
 <!-- 如果有user:add許可權才顯示  使用者增加 -->
 <a href="#">  使用者增加</a><br/>
 </shiro:hasPermission>
 <shiro:hasPermission name="user:edit">
 <!-- 如果有user:edit許可權才顯示  使用者編輯 -->
 <a href="#"> 使用者編輯</a><br/>
 </shiro:hasPermission>
 <shiro:hasPermission name="user:delete">
 <!-- 如果有user:delete許可權才顯示  使用者刪除 -->
 <a href="#">  使用者刪除</a><br/>
 </shiro:hasPermission>
</body>
</html>

2. Shiro整合SpringMVC基於註解

2.1. 配置流程說明

2.1.1. 第一步:配置webx.xml

 <filter>
 <filter-name>securityFilterBean</filter-name>
 <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
 <!-- 將生命週期交給Spring代理 -->
 <init-param>
 <param-name>targetFilterLifecycle</param-name>
 <param-value>true</param-value>
 </init-param>
 </filter>
 <filter-mapping>
 <filter-name>securityFilterBean</filter-name>
 <url-pattern>/*</url-pattern>
 </filter-mapping>

2.1.2. 第二步:配置Shiro配置類

package cn.gzsxt.config;
 
import java.util.LinkedHashMap;
import java.util.Map;
 
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
import cn.gzsxt.realm.ShiroRealm;
 
@Configuration
public class ShiroConfig {
 
 //1.配置securityFilterBean物件
 @Bean(name="securityFilter")
 public Object getShiroFilterFactory() {
        ShiroFilterFactoryBean factory=new ShiroFilterFactoryBean();
 
 //設定屬性
 factory.setLoginUrl("/login");
 factory.setSuccessUrl("/index");
 factory.setSecurityManager(this.getSecurityManager());
 //基於配置的許可權過濾器,順序執行,所以使用LinkedHashMap
        Map<String, String> filterChainDefinition=new LinkedHashMap<>();
 filterChainDefinition.put("/**", "authc");
 factory.setFilterChainDefinitionMap(filterChainDefinition);
 
        Object securityFilter=null;
 try {
 securityFilter = factory.getObject();
        } catch (Exception e) {
 e.printStackTrace();
        }
 return securityFilter;
    }
 
 //2.獲得securityManager物件
 @Bean(name="securityManager")
 public DefaultWebSecurityManager getSecurityManager() {
        DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
 //設定需要的realm物件
 securityManager.setRealm(this.getRealm());
 return securityManager;
    }
 
 //3.配置realm物件
 @Bean
 public ShiroRealm getRealm(){
        ShiroRealm realm=new ShiroRealm();
 return realm;
    }
 
}