shiro中文api_Shiro
1 shiro
Apache shiro 是一個 Java 安全框架。
功能:認證、授權、加密和會話管理功能
應用環境:JavaEE、JavaSE
Subject 可看做成一個用戶
SecurityManager 框架的核心API
Reaim 域對象,用于取數據庫中的數據,進行權限比對。
| 名詞 | 名詞中文解釋 | | -------------- | ------------ | | Subject | 主體 | | Security | 安全 | | Realm | 領域、范圍 | | Authenticator | 認證器 | | Authentication | 認證 | | Authorizer | 授權器 | | Authorization | 授權 | | Cryptography | 密碼、憑證 | | Credential | 證書、憑證 | | Matcher | 匹配器 | | Principal | 身份 |
shiro 配置文件
shiro.ini 文件放在 claspath 中,shiro會自動查找。其中格式是key/value鍵值對配置。
Ini 配置文件一般適合與用戶少且不需要在運行時動態創建的情景下使用。
ini 配置文件有四大類:main,users,roles,urls
[main]
main 主要配置shiro 的一些對象,例如:securityManager,Realm,authenticator,authcStrategy
[users]
作用:配置一組靜態的用戶
格式:key:value ,key表示密碼的名字,value 表示密碼的值
zeros=1233[roles]
作用:將角色和權限關聯操作
格式:資源:操作
role1= printer:create,printer:query[urls]
作用:攔截對應的 URL 請求。
2 實現簡單認證
認證:驗證用戶是否合法。
2.1 實現步驟
導入 jar 包
junit-4.9.jar log4j-1.2.17.jar shiro-all-1.3.2.jar slf4j-api-1.7.5.jar slf4j-log4j12-1.7.5.jar
編寫 shiro.ini 配置文件
[users]zeros=1233測試
package com.szxy.shiro;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; import org.junit.Test;public class SampleAuthentication {@Testpublic void sampleAuthentication(){//構建 SecurityManagerFactory 工廠IniSecurityManagerFactory factory = new IniSecurityManagerFactory();//利用 SecurityManagerFactory 實例化 SecurityManager 對象SecurityManager securityManager = factory.getInstance();// 將 SecurityManager 設置到運行環境中SecurityUtils.setSecurityManager(securityManager);//通過SecurityUtils, 創建主體 SubjectSubject subject = SecurityUtils.getSubject();//創建用戶密碼令牌認證UsernamePasswordToken token = new UsernamePasswordToken("admin1","passwd");//驗證身份subject.login(token);//查看結果System.out.println(subject.isAuthenticated());} }3 Realm 域
shiro 默認使用 IniRealm 源,默認從 init 配置文件中讀取用戶信息。
3.1 實現步驟
建立 users 表
注意:表名必須是 users 。jdbcRealm 查找數據庫中的表就是 users 表。
導入 jar 包
com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar commons-beanutils-1.9.2.jar commons-logging-1.1.1.jar junit-4.9.jar log4j-1.2.17.jar mysql-connector-java-5.1.30.jar shiro-all-1.3.2.jar slf4j-api-1.7.5.jar slf4j-log4j12-1.7.5.jar
編寫 shiro.ini 配置文件
[main] #配置Realm jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm #配置數據源 dataSource = com.mchange.v2.c3p0.ComboPooledDataSource dataSource.driverClass = com.mysql.jdbc.Driver dataSource.jdbcUrl = jdbc:mysql:///rbac dataSource.user = root dataSource.password = rootjdbcRealm.dataSource = $dataSource#將 Realm 注入給 SecurityManager securityManager.realm = $jdbcRealm測試
同簡單認證的測試方法
4 自定義 Realm
好處:可以給 securityManager 更加靈活的安全數據源(eg。jdbcRealm 中表和字段都限定了)
方式:通過實現 Realm 接口,或根據需要繼承他的響應子類即可。 AuthenticatingRealm
需求: 使用自定義 Realm ,從而實現認證。
實現步驟
導入 jar 包
com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar commons-beanutils-1.9.2.jar commons-logging-1.1.1.jar junit-4.9.jar log4j-1.2.17.jar mysql-connector-java-5.1.30.jar shiro-all-1.3.2.jar slf4j-api-1.7.5.jar slf4j-log4j12-1.7.5.jar
編寫自定義 Realm
package com.szxy.realm;import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement;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.realm.AuthenticatingRealm; import org.apache.shiro.subject.PrincipalCollection;import com.mysql.jdbc.Driver;public class CustRealm extends AuthenticatingRealm {private String principals; //用戶名private String credentials; //密碼private String driverName = "com.mysql.jdbc.Driver";private String url = "jdbc:mysql:///rbac";private String user = "root";private String password = "root";@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {// 使用 jdbc 連接數據庫Connection conn = null;Statement stat = null;ResultSet rs = null;try {//注冊驅動/*Driver driver = new Driver();DriverManager.registerDriver(driver);*/Class.forName(driverName);//獲取數據庫連接conn = DriverManager.getConnection(url, user, password);//操作數據庫對象stat = conn.createStatement();//定義 sql 語句String sql = "select username,password from users";//執行 查詢語句rs = stat.executeQuery(sql);//獲取 結果集if(rs.next()){principals = rs.getString("username");credentials = rs.getString("password");}} catch (SQLException | ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{if(rs!=null){try {rs.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(stat!=null){try {stat.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(conn !=null){try {conn.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}//創建 AuthenticationInfo 接口 實現類SimpleAuthenticationInfo info =new SimpleAuthenticationInfo(principals, credentials,"custRealm");return info;} }編寫 shiro.ini 配置文件
[main] #配置Realm custRealm = com.szxy.realm.CustRealm#將 Realm 注入給 SecurityManager securityManager.realm = $custRealm測試
同上測試
5 加密方式
對稱加密算法
加密的密鑰與解密的密鑰相同
非對稱算法算法
加密的密鑰與解密的密鑰不相同
公開密鑰(publickey:簡稱公鑰)和私有密鑰(privatekey:簡稱私鑰)。
公鑰與私鑰是一對,如果用公鑰對數據進行加密,只有用對應的私鑰才能解密。
對稱與非對稱算法
散列算法比較
MD5加密、加鹽與迭代
加鹽
原因:相同的 password 生產相同的 Hash 值是相同
原理:給原文加入隨機數生成新的MD5
加鹽 salt:指往原文加入的隨機數
迭代
加密的次數
| Md5Hash的構造方法 | 參數名用法 | | ------------------------------------------------------------ | ----------------------- | | public Md5Hash(Object source) | source指加密的數據 | | public Md5Hash(Object source, Object salt) | salt 加鹽 | | public Md5Hash(Object source, Object salt, int hashIterations) | hashIterations 迭代次數 | | public Md5Hash() | 無參構造器 |
代碼示例
package com.szxy.md5;import org.apache.shiro.crypto.hash.Md5Hash;public class TestMd5 {public static void main(String[] args) {//直接加密 Md5Hash md5 = new Md5Hash("123");System.out.println(md5);//202cb962ac59075b964b07152d234b70//加鹽 salt md5 = new Md5Hash("123", "zwz");System.out.println(md5); //3b52ecfc4719fcb6c863208063548792//迭代,即加密的次數md5 = new Md5Hash("123", "zwz", 2);System.out.println(md5); //de231265fe7ec45af1404ded2f365001 } }6 憑證匹配器 Authentication
AuthenticatingRealm
修改 realm
//ByteSource.Utilbytes(salt) package com.szxy.realm;import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement;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.realm.AuthenticatingRealm; import org.apache.shiro.util.ByteSource;public class CustRealm extends AuthenticatingRealm{private String principals; //用戶名private String credentials; //密碼private String driverName = "com.mysql.jdbc.Driver";private String url = "jdbc:mysql:///shiro";private String user = "root";private String password = "root";private String salt = null; //加鹽的鹽值@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {// 使用 jdbc 連接數據庫Connection conn = null;Statement stat = null;ResultSet rs = null;try {//注冊驅動/*Driver driver = new Driver();DriverManager.registerDriver(driver);*/Class.forName(driverName);//獲取數據庫連接conn = DriverManager.getConnection(url, user, password);//操作數據庫對象stat = conn.createStatement();//定義 sql 語句String sql = "select username,password,salt from starUsers";//執行 查詢語句rs = stat.executeQuery(sql);//獲取 結果集if(rs.next()){principals = rs.getString("username");credentials = rs.getString("password");salt = rs.getString("salt");}} catch (SQLException | ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{if(rs!=null){try {rs.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(stat!=null){try {stat.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(conn !=null){try {conn.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}ByteSource byteSource = ByteSource.Util.bytes(salt); //加鹽//創建 AuthenticationInfo 接口 實現類SimpleAuthenticationInfo info =new SimpleAuthenticationInfo(principals, credentials,byteSource,"customRealm");return info;} }配置 shiro 配置文件
[main]#配置憑證匹配器 credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher#設置憑證匹配器的相關屬性 credentialsMatcher.hashAlgorithmName=MD5 credentialsMatcher.hashIterations=2#配置Realm customRealm=com.szxy.realm.CustRealm#配置Realm的憑證匹配器屬性 customRealm.credentialsMatcher=$credentialsMatcher#將Realm注入給SecurityManager securityManager.realm=$customRealm7 授權 Authorization
授權,又稱訪問控制,是對資源訪問管理的過程。
即對于認證通過的用戶,授予他可以訪問某些資源的權限
授權方式
代碼觸發、注解觸發、標簽觸發
授權流程圖
配置文件
[main]#配置憑證匹配器 credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher#設置憑證匹配器的相關屬性 credentialsMatcher.hashAlgorithmName=MD5 credentialsMatcher.hashIterations=2#配置Realm customRealm=com.szxy.realm.CustRealm#配置Realm的憑證匹配器屬性 customRealm.credentialsMatcher=$credentialsMatcher#將Realm注入給SecurityManager securityManager.realm=$customRealm代碼示例
package com.szxy.realm;import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement;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.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthenticatingRealm; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource;public class CustRealm extends AuthorizingRealm{private String principals; //用戶名private String credentials; //密碼private String driverName = "com.mysql.jdbc.Driver";private String url = "jdbc:mysql:///shiro";private String user = "root";private String password = "root";private String salt = null; //加鹽的鹽值private String roleName; //角色名稱private String remark;// 驗證的方法@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {// 使用 jdbc 連接數據庫Connection conn = null;Statement stat = null;ResultSet rs = null;try {//注冊驅動/*Driver driver = new Driver();DriverManager.registerDriver(driver);*/Class.forName(driverName);//獲取數據庫連接conn = DriverManager.getConnection(url, user, password);//操作數據庫對象stat = conn.createStatement();//定義 sql 語句String sql = "select username,password,salt from starUsers";//執行 查詢語句rs = stat.executeQuery(sql);//獲取 結果集if(rs.next()){principals = rs.getString("username");credentials = rs.getString("password");salt = rs.getString("salt");}} catch (SQLException | ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{if(rs!=null){try {rs.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(stat!=null){try {stat.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(conn !=null){try {conn.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}ByteSource byteSource = ByteSource.Util.bytes(salt); //加鹽//創建 AuthenticationInfo 接口 實現類SimpleAuthenticationInfo info =new SimpleAuthenticationInfo(principals, credentials,byteSource,"customRealm");return info;}// 授權的方法@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {// 使用 jdbc 連接數據庫Connection conn = null;Statement stat = null;ResultSet rs = null;try {//注冊驅動/*Driver driver = new Driver();DriverManager.registerDriver(driver);*/Class.forName(driverName);//獲取數據庫連接conn = DriverManager.getConnection(url, user, password);//操作數據庫對象stat = conn.createStatement();//定義 sql 語句//String sql = "select rolename from roles";String sql = "select * from permission"; //執行 查詢語句rs = stat.executeQuery(sql);//獲取 結果集if(rs.next()){//roleName = rs.getString("rolename");remark = rs.getString("remark");}} catch (SQLException | ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{if(rs!=null){try {rs.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(stat!=null){try {stat.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(conn !=null){try {conn.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //info.addRole(roleName); //添加角色信息info.addStringPermission(remark); //添加權限信息return info;} }測試
package com.szxy.shiro;import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.crypto.hash.Md5Hash; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.subject.Subject; import org.junit.Test;public class TestShiro {@Testpublic void TestAuthorization(){//構建 SecurityManagerFactory 工廠IniSecurityManagerFactory factory = new IniSecurityManagerFactory();//利用 SecurityManagerFactory 實例化 SecurityManager 對象SecurityManager securityManager = factory.getInstance();// 將 SecurityManager 設置到運行環境中SecurityUtils.setSecurityManager(securityManager);//通過SecurityUtils, 創建主體 SubjectSubject subject = SecurityUtils.getSubject();//創建用戶密碼令牌認證UsernamePasswordToken token = new UsernamePasswordToken("admin","123");//驗證身份subject.login(token);//查看結果System.out.println(subject.isAuthenticated());//驗證權限//基于角色授權boolean flag = subject.hasRole("管理員1");System.out.println(flag);//權限授權boolean flag2 = subject.isPermitted("一級菜單,基本設置操作權限");System.out.println(flag2);}}8 spring 整合Shiro
新建項目,導入 jar 包
編寫配置文件
編寫 web.xml
DelegatingFilterProxy
通過代理模式將 servlet 容器中 filter 同 spring 容器的 bean 關聯起來
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"><display-name>RBACDemo</display-name><welcome-file-list><welcome-file>index.html</welcome-file><welcome-file>index.htm</welcome-file><welcome-file>index.jsp</welcome-file><welcome-file>default.html</welcome-file><welcome-file>default.htm</welcome-file><welcome-file>default.jsp</welcome-file></welcome-file-list><!-- 監聽 ServletContext ,注冊 Spring 容器 --><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- 指定 spring 配置文件的名稱及位置 --><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext-*.xml</param-value></context-param><!-- 注冊 SpringMVC 容器 --><servlet><servlet-name>DispatcherServlet</servlet-name><servlet-class> org.springframework.web.servlet.DispatcherServlet</servlet-class><!-- 指定 SpringMVC 配置文件的位置 --><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:SpringMVC.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><!-- 開啟編碼過濾器 --><filter><filter-name>CharacterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>utf-8</param-value></init-param><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><!-- 注冊 DelegatingFilterProxy 通過代理模式將 servlet 容器中 filter 同 spring 容器的 bean 關聯起來--><filter><filter-name>delegatingFilterProxy</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class><!--該屬性為 true 表名啟用引用 filter 的init() 和 destroy() --><init-param><param-name>targetFilterLifecycle</param-name><param-value>true</param-value></init-param><!--該屬性設置 spring 容器中 filter 的bean的 id--><init-param><param-name>targetBeanName</param-name><param-value>shiroFilter</param-value></init-param> </filter><filter-mapping><filter-name>delegatingFilterProxy</filter-name><url-pattern>/*</url-pattern></filter-mapping> </web-app>spring-shiro.xml
<!-- 注冊憑證匹配器,并為其注入屬性值--> <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"><!-- 加密方式 --><property name="hashAlgorithmName" value="md5"></property><!-- 迭代次數 --><property name="hashIterations" value="2" ></property> </bean><!-- 注冊自定義 realm --> <bean id="customRealm" class="com.szxy.realm.CustomRealm"><property name="credentialsMatcher" ref="credentialsMatcher"></property> </bean><!-- 注冊 SecurityManager --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><property name="realm" ref="customRealm"></property> </bean><!--注冊 shiroFilterFactoryBean 注意:bean 的id 名稱必須與過濾器中的名稱一致--> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><property name="securityManager" ref="securityManager"></property><property name="loginUrl" value="/login.do"></property><property name="successUrl" value="/jsp/users.jsp"></property><property name="unauthorizedUrl" value="/jsp/refuse.jsp"></property><!-- 設置過濾器鏈屬性 --><property name="filterChainDefinitions"><value>/login.do=authc/**=anon</value></property> </bean>代碼示例
9 DelegatingFilterProxy
DelegatingFilterProxy 源碼分析
void initFilterBean() 初始化過濾器 bean 對象,并調用 Filter initDelegate(WebApplicationContext wac) 方法,
從 spring 容器取出 目標 target 的bean 對象,并對其他進行初始化操作。
@Override protected void initFilterBean() throws ServletException {synchronized (this.delegateMonitor) {if (this.delegate == null) {// If no target bean name specified, use filter name.if (this.targetBeanName == null) {this.targetBeanName = getFilterName();}// Fetch Spring root application context and initialize the delegate early,// if possible. If the root application context will be started after this// filter proxy, we'll have to resort to lazy initialization.WebApplicationContext wac = findWebApplicationContext();if (wac != null) {this.delegate = initDelegate(wac); }}}//Initialize the Filter delegate, defined as bean the given Spring protected Filter initDelegate(WebApplicationContext wac) throws ServletException {Filter delegate = wac.getBean(getTargetBeanName(), Filter.class);if (isTargetFilterLifecycle()) {//該屬性為 true 表名啟用引用 filter 的init() 和 destroy() 交給 spring 容器管理 delegate.init(getFilterConfig());}return delegate; }10 spring 整合 Shiro 之注冊
密碼使用 md5 方式加密
表單序列化
使用該操作,可以直接獲取表單數據,簡化操作。
<script type="text/javascript" src="js/jquery-1.7.2.min.js"></script><script type="text/javascript" >$(function(){$("#btn").click(function(){$.ajax({url:"/user/register",type:"POST",data:$("#myForm").serialize(),//表單序列化,傳遞表單數據success:function(data){alert(data);}});});}); </script>md5加密
@Override public int userRegister(User user) {//使用 md5 加密用戶的密碼,并使用用戶名作為 salt 值Md5Hash newPassword = new Md5Hash(user.getPassword(),user.getUsername(), 2);user.setPassword(newPassword.toString());user.setSalt(user.getUsername());return userMapper.insertUser(user); }9 實現菜單授權
11 SessionMapper 的使用
sessionMamanager 會話管理器管理著應用中所有的 Subject 的會話的創建、維護、刪除、失效、驗證等工作。
Shiro 提供了三個默認實現類:
| 類名 | 功能 | | ------------------------------ | ------------------------------------------------------------ | | DefaultSessionManager | 用于 JavaSE 環境 | | ServletContainerSessionManager | 用于 Web 環境,直接使用 tomcat 容器管理對象 | | DefaultWebSessionManager | 用于Web 環境,替代 類名功能DefaultSessionManager用于 JavaSE 環境ServletContainerSessionManager,自己維護會話。 |
<!-- 注冊 sessionManager --> <bean id="sessionManager" class="org.apache.shiro.session.mgt.DefaultSessionManager"><!-- 設置 session 超時時間 ,以毫秒為單位 ms 1s 等于 1000ms --><property name="globalSessionTimeout" value="500000"></property><property name="deleteInvalidSessions" value="true"></property> </bean>12 remeber me 功能實現
即登錄成功后,下次免登錄
實現步驟
用戶類即及其引用類的都需要序列化
修改頁面 index .jsp
修改 Spring-shiro.xml
13 Shiro 內置過濾器
1 認證過濾器
anon authcBasic auchc user
2 授權過濾器
perms roles ssl rest port
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><property name="securityManager" ref="securityManager"></property><property name="loginUrl" value="/user/login.do"></property><property name="successUrl" value="/user/loginSuccess.do"></property><property name="unauthorizedUrl" value="/jsp/refuse.jsp"></property><!-- 設置過濾器鏈屬性 authc 認證過濾器,表示表單認證anon 放行,可以匿名訪問,不需要認證user 用戶過濾器,用于識別當前用戶是否登錄并保存密碼 RememberMe--><property name="filterChainDefinitions"><value>/user/login.do=authc /user/loginSuccess.do=user/menu/showMenu.do=user/**=anon</value></property> </bean>注意
使用 Shiro 框架做用戶登錄的時候,若登錄成功后,在使用瀏覽器回來之前的登錄界面,這時就登錄不上了,不僅是使用之前登錄的賬號,還是其他賬號。
推測:可能是同一 瀏覽器登錄后存在 cookie ,影響用戶的二次登錄。
總結
以上是生活随笔為你收集整理的shiro中文api_Shiro的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows下安装tensorflow
- 下一篇: git本地库(操作具体命令)