1. 程式人生 > >shiro 簡單登入demo

shiro 簡單登入demo

1.shiro 是java強大的安全認證框架

  1. shiro框架的核心功能:認證,授權,會話管理,加密
  2. shiro框架認證流程

 

Application Code:應用程式程式碼,由開發人員負責開發的

Subject:框架提供的介面,代表當前使用者物件

SecurityManager:框架提供的介面,代表安全管理器物件

Realm:可以開發人員編寫,框架也提供一些,類似於DAO,用於訪問許可權資料

 

 

2.shiro +ssm 登入demo

第一步:引入shiro框架相關的jar

 第二步:在web.xml中配置spring框架提供的用於整合shiro框架的過濾器

<!-- shiro filter  -->
  <filter>
          <!-- filter-name必須和配置shiro的過濾工廠bena 的id相同名 -->
          <filter-name>shiroFilter</filter-name>
          <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  </filter>
 
  <filter-mapping>
          <filter-name>shiroFilter</filter-name>
          <url-pattern>/*</url-pattern>
  </filter-mapping>
 

第三步:在spring-shiro.xml配置檔案中配置bean,id為shiroFilter

<!-- 配置shiro的過濾工廠bena -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
        <property name="loginUrl" value="/admin/login.jsp"/>
        <property name="successUrl" value="/admin/home/home.jsp"/>
        <property name="unauthorizedUrl" value="/unauthorized.jsp"/>
        <!--指定url攔截策越  -->
        <property name="filterChainDefinitions">
            <value>
                /css/** = anon
                /js/** =anon
                /images/** = anon
                /login.jsp* =anon
                /register.jsp* =anon
                /login.do* =anon
                /register.do* =anon
                /checkUser.do* =anon
                /* =authc
            </value>
        </property>
    </bean>

第四步:配置安全管理器

 <!-- 安全管理器供工廠注入 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> </bean>

第五步:修改UserController中的login方法,使用shiro提供的方式進行認證操作 

        /*
	 * 使用者登入,使用shiro提供的方式驗證
	 */
	@RequestMapping(value = "/login.do")
	public String login(User u, Model model, HttpSession session) {
		
		//獲得當前使用者到登入物件,現在狀態為未認證
		Subject subject=SecurityUtils.getSubject();
		//使用者名稱密碼令牌
		AuthenticationToken token=new UsernamePasswordToken(u.getUsername(),Md5Utils.md5(u.getPassword()));
		//shiro 使用異常捕捉登入失敗訊息
		try {
			//將令牌傳到shiro提供的login方法驗證,需要自定義realm
			subject.login(token);
			//沒有異常表示驗證成功
			User user=uservice.login(u);
			session.setAttribute("user", user);
			return "/home/home";
		} catch (IncorrectCredentialsException ice){
           model.addAttribute("error","使用者名稱或密碼不正確!");
        }catch(UnknownAccountException uae){
        	
        	 model.addAttribute("logininfo","未知賬戶!");
        }catch(LockedAccountException lae){
        	 
        	 model.addAttribute("logininfo","賬戶已鎖定!");
        }catch(ExcessiveAttemptsException eae){
        	 
        	 model.addAttribute("logininfo","使用者名稱或密碼錯誤次數太多!");
        }catch(AuthenticationException ae){
            ae.printStackTrace();
            model.addAttribute("logininfo","驗證未通過!");
        }catch (Exception e) {
        	 model.addAttribute("logininfo","驗證未通過!");
		}
		return "/login";
	}

第六步:自定義realm,並注入給安全管理器

public class MyShiroRealm extends AuthorizingRealm {
	
	
	@Autowired
	private UserServiceImpl service;
	
	//授權方法
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
		// TODO 未書寫許可權,只演示登入認證
		return null;
	}
	
	//認證訪法
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		System.out.println("realm------------------------");
		UsernamePasswordToken mytoken=(UsernamePasswordToken) token;
		String username=mytoken.getUsername();
		User u=new User();
		u.setUsername(username);
		
		//根據使用者名稱查詢資料·庫中的密碼
		User user = service.login(u);
		if(user==null) {
			//使用者不存在
			return null;
		}
		//如果能查詢到,再由框架比對資料庫中查詢到的密碼和頁面提交的密碼是否一致
		AuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),this.getName());
		
		return info;
	}

}

注入安全管理器  (自定義realm中注入的service層查資料庫,啟動專案時會注入失敗,需要在注入realm之前,注入service層bean

(   <!-- realm 需要先注入service -->
       <context:component-scan base-package="com.sj.serviceimpl"/>

這的service層和dao層就不再提供了,因為很簡單,就是一個根據使用者名稱查詢放回使用者資訊的介面

<!-- 安全管理器供工廠呼叫 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <!-- 注入自己的realm -->
        <property name="realm" ref="myRealms"/>
    </bean>
    
    <!--自定義realm  -->
    <bean id="myRealms" class="com.sj.shiro.MyShiroRealm"/>

完整的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" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
">
    
    <!-- realm 需要先注入service -->
    <context:component-scan base-package="com.sj.serviceimpl"/>
    
    <!-- 配置shiro的過濾工廠bena -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
        <property name="loginUrl" value="/admin/login.jsp"/>
        <property name="successUrl" value="/admin/home/home.jsp"/>
        <property name="unauthorizedUrl" value="/unauthorized.jsp"/>
        <!--指定url攔截策越  -->
        <property name="filterChainDefinitions">
            <value>
                /css/** = anon
                /js/** =anon
                /images/** = anon
                /login.jsp* =anon
                /register.jsp* =anon
                /login.do* =anon
                /register.do* =anon
                /checkUser.do* =anon
                /* =authc
            </value>
        </property>
    </bean>
    
    <!-- 安全管理器供工廠呼叫 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <!-- 注入自己的realm -->
        <property name="realm" ref="myRealms"/>
    </bean>
    
    <!--自定義realm  -->
    <bean id="myRealms" class="com.sj.shiro.MyShiroRealm"/>

</beans>

 shiro配置檔案需要引入到spring中,在web.xml原來的spring檔案匯入中新增 classpath:spring-shiro.xml

<context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:applicationContext.xml,
                  classpath:spring-shiro.xml
      </param-value>
  </context-param>