如果想使用Relam的操作,那么必須要保證有一個具體的認證類實現了Relam接口
web.xml增加shiro的配置
<!-- 進行shiro的過濾器的配置 --> <filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <!-- 該參數表示shiro的生命周期將交由Spring容器進行管理(默認情況下,取值為false) --> <!-- 如果將其內容設置為true,則表示由Servlet容器進行管理 --> <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> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> <dispatcher>ERROR</dispatcher> </filter-mapping> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list>
在applicationContext.xml加入shiro配置項信息
配置shiro的登錄入口
<!-- 此處表示使用內置的表單登錄控制驗證 --> <bean id="formAuthenticationFilter" class="com.sk.shiro.MyFormAuthenticationFilter"> <!-- 定義出需要使用的參數,此參數與表單一一對應 --> <property name="usernameParam" value="username"/> <property name="passwordParam" value="password"/> <!-- <property name="loginUrl" value="/login.jsp"/> 不用配置 默認是這個 --> </bean>
配置Shiro過濾器
<!-- 配置shiro過濾器 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!-- 表示現在要配置的是一個安全管理器 --> <property name="securityManager" ref="securityManager"/> <!-- 登錄成功之后的跳轉訪問路徑 --> <property name="successUrl" value="/index.jsp"/> <!-- 配置shiro里面需要使用到的過濾器操作 --> <property name="filters"> <map> <entry key="authc" value-ref="formAuthenticationFilter"/> </map> </property> <!-- shiro里面需要針對於所有的路徑進行配置,所有的配置需要通過文本的形式設置 --> <property name="filterChainDefinitions"> <value> /login.jsp=authc<!--loginUrl 需要和loginUrl一致 --> /successUrl=authc /test/*=user /test*=user </value> </property> </bean>
配置SecurityManager管理器
<!-- 配置SecurityManager的管理 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <!-- 配置你需要使用的Realms --> <property name="realms"> <list> <ref bean="usernamePasswordRealm"/> </list> </property> <!-- 定義要使用的session管理器 --> <property name="sessionManager" ref="sessionManager"/> </bean>
編寫UsernamePasswordRealm進行認證授權
package com.sk.shiro; import java.util.HashSet; import java.util.Set; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authc.UnknownAccountException; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; public class UsernamePasswordRealm extends AuthorizingRealm { @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { System.out.println("********** 2、用戶角色與權限:doGetAuthorizationInfo **********"); String username = (String) principals.getPrimaryPrincipal() ; // 取得用戶登錄名 SimpleAuthorizationInfo auth = new SimpleAuthorizationInfo() ; // 定義授權信息的返回數據 try { Set<String> allRoles = new HashSet<>(); allRoles.add("admin"); Set<String> allActions = new HashSet<>(); auth.setRoles(allRoles);// 所有的角色必須以Set集合的形式出現 auth.setStringPermissions(allActions); // 所有的權限必須以Set集合的形式出現 } catch (Exception e) { e.printStackTrace(); } return auth; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) { System.out.println("********** 1、用戶登錄認證:doGetAuthenticationInfo() **********"); // 1、登錄認證的方法需要先執行,需要用他來判斷登錄的用戶信息是否合法 String username = (String) token.getPrincipal() ; // 取得用戶名 if(!"admin".equals(username)) { throw new UnknownAccountException("用戶名不存在"); } // 需要通過用戶名取得用戶的完整信息,利用業務層操作 String password = (String) token.getCredentials(); System.err.println("密碼"+password); AuthenticationInfo auth = new SimpleAuthenticationInfo(username, password, "myRealm") ; return auth ; } @Override public boolean supports(AuthenticationToken token) { MyAuthenticationToken t=null; try { t = (MyAuthenticationToken) token; } catch (Exception e) { e.printStackTrace(); } return t.getLoginType() == LoginType.USERNAME_PASSWORD; } }
這是首頁登錄的jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"//"+request.getServerName()+":"+request.getServerPort(); %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <%-- <base href="<%=basePath %>"> --%> <%System.out.println("---"+basePath); %> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Shiro</title> </head> <body> <form action="/login.jsp" method = "post"> 用戶名<input type="text" name = "username" id = "username"><br> 密碼 <input type="password" name = "password" id = "password"><br> <input type="hidden" name = "loginType" value = "USERNAME_PASSWORD"> <input type="submit" value="登錄"> <input type="reset" value="重置"> </form> </body> </html>
shiro登錄的流程
從登陸的jsp的action找到配置的formAuthenticationFilter(此接口中有createToken等方法 根據登陸方式可以使用自定義token 實現HostAuthenticationToken, RememberMeAuthenticationToken接口 可以自定義token )
然后登錄的路徑被shiroFilter過濾
shiroFilter交給配置的securityManager去管理
securityManager又交給配置的usernamePasswordRealm去授權和認證(supports()方法返回true代表使用這個Realm去認證 此處為了兼容多種登陸方式 比如手機驗證碼、用戶名密碼 等)
登錄成功之后的跳轉訪問路徑
<property name="successUrl" value="/index.jsp"/>
