智能供銷系統_4shiro

今天的任務是在原有的框架中集成shirojava

 


  1.shiro的認識
> 權限框架(提供的易用的API,功能強大)web

   1.1 和Spring security區別
 
框架       | shiro | Spring security
          ---|------| ---
  易用性  |   √    | X
  粒度      | 粗     | 細(強大)算法

   1.2 shiro的四大基石
> 身份驗證、受權、密碼學和會話管理
> securityManager:核心對象  realm:獲取數據接口spring


  2.shiro的核心api
   2.1 操做以前,先獲得securityManager對象
```數據庫

//一.建立咱們本身的Realm
MyRealm myRealm = new MyRealm();

//二.搞一個核心對象:
DefaultSecurityManager securityManager = new DefaultSecurityManager();
securityManager.setRealm(myRealm);

//三.把securityManager放到上下文中
SecurityUtils.setSecurityManager(securityManager);


```apache

## 2.2 咱們使用過的方法api

```app

//1.拿到當前用戶
Subject currentUser = SecurityUtils.getSubject();
//2.判斷是否登陸
currentUser.isAuthenticated();
//3.登陸(須要令牌的)
/**
    UnknownAccountException:用戶名不存在
    IncorrectCredentialsException:密碼錯誤
    AuthenticationException:其它錯誤
*/
 UsernamePasswordToken token = new UsernamePasswordToken("admin", "123456");
 currentUser.login(token);
 
//4.判斷是不是這個角色/權限
currentUser.hasRole("角色名")
currentUser.isPermitted("權限名")


```
# 3.密碼加密功能
```框架

/**
 * String algorithmName, Object source, Object salt, int hashIterations)
 * 第一個參數algorithmName:加密算法名稱
 * 第二個參數source:加密原密碼
 * 第三個參數salt:鹽值
 * 第四個參數hashIterations:加密次數
 */
SimpleHash hash = new SimpleHash("MD5","123456","itsource",10);
System.out.println(hash.toHex());
```

# 4.自定義Realm
> 繼承AuthorizingRealm
>> 實現兩個方法:doGetAuthorizationInfo(受權)  /doGetAuthenticationInfo(登陸認證)

```
//身份認證
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
    //1.拿用戶名與密碼
    UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
    String username = token.getUsername();
    //2.根據用戶名拿對應的密碼
    String password = getByName(username);
    if(password==null){
        return null; //返回空表明用戶名有問題
    }
    //返回認證信息
    //準備鹽值
    ByteSource salt = ByteSource.Util.bytes("asdf");
    //密碼是shiro本身進行判斷
    SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username,password,salt,getName());
    return authenticationInfo;
}



//受權
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    //拿到用戶名  Principal:主體(用戶對象/用戶名)
    String username = (String)principalCollection.getPrimaryPrincipal();
    //拿到角色
    Set<String> roles = findRolesBy(username);
    //拿到權限
    Set<String> permis = findPermsBy(username);
    //把角色權限交給用戶
    SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
    authorizationInfo.setRoles(roles);
    authorizationInfo.setStringPermissions(permis);
    return authorizationInfo;
}


> 注意:若是咱們的密碼加密,應該怎麼判斷(匹配器)jsp

//一.建立咱們本身的Realm
MyRealm myRealm = new MyRealm();
//建立一個憑證匹配器(沒法設置鹽值)
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
//  使用MD5的方式比較密碼
matcher.setHashAlgorithmName("md5");
// 設置編碼的迭代次數
matcher.setHashIterations(10);
//設置憑證匹配器(加密方式匹配)
myRealm.setCredentialsMatcher(matcher);


```


# 5.集成Spring
> 去找:shiro-root-1.4.0-RC2\samples\spring

## 5.1 導包
```

<!-- 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>

 

## 5.2 web.xml> 這個過濾器是一個代碼(只關注它的名稱)
 

<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>

 

## 5.3 application-shiro.xml

> 在我們的application引入

`<import resource="classpath: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">


    <!-- 建立securityManager這個核心對象 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <!-- 設置一個realm進去 -->
        <property name="realm" ref="jpaRealm"/>
    </bean>

    <!-- 被引用的realm(必定會寫一個自定義realm) -->
    <bean id="jpaRealm" class="cn.xxx.aisell.shiro.JpaRealm">
        <!-- 爲這個realm設置相應的匹配器 -->
        <property name="credentialsMatcher">
            <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                <!-- 設置加密方式 -->
                <property name="hashAlgorithmName" value="md5"/>
                <!-- 設置加密次數 -->
                <property name="hashIterations" value="10" />
            </bean>
        </property>
    </bean>

    <!--  可讓我們的權限判斷支持【註解】方法 -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
          depends-on="lifecycleBeanPostProcessor"/>
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"/>
    </bean>


    <!--  真正實現權限的過濾器 它的id名稱和web.xml中的過濾器名稱同樣 -->
    <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/main.jsp"/>
        <!-- 沒有權限跳轉的路徑 -->
        <property name="unauthorizedUrl" value="/s/unauthorized.jsp"/>
        <!--
            anon:這個路徑不須要登陸也能夠訪問
            authc:須要登陸才能夠訪問
            perms[depts:index]:作權限攔截
                我們之後哪些訪問有權限攔截,須要從數據庫中讀取
        -->
        <!--
        <property name="filterChainDefinitions">
            <value>
                /s/login.jsp = anon
                /login = anon
                /s/permission.jsp = perms[user:index]
                /depts/index = perms[depts:index]
                /** = authc
            </value>
        </property>
        -->
        <property name="filterChainDefinitionMap" ref="filterChainDefinitionMap" />
    </bean>
    <!-- 實例工廠設置 -->
    <bean id="filterChainDefinitionMap"
          factory-bean="filterChainDefinitionMapFactory"
          factory-method="createFilterChainDefinitionMap" />
    <!-- 建立能夠拿到權限map的bean -->
    <bean id="filterChainDefinitionMapFactory" class="cn.itsource.aisell.shiro.FilterChainDefinitionMapFactory" />
</beans>

```

5.4 獲取Map過濾

> 注意,返回的Map必需是有序的(LinkedHashMap)```

public class FilterChainDefinitionMapFactory {

    /**
     * 後面這個值會從數據庫中來拿
     * /s/login.jsp = anon
     * /login = anon
     * /s/permission.jsp = perms[user:index]
     * /depts/index = perms[depts:index]
     * /** = authc
     */
    public Map<String,String> createFilterChainDefinitionMap(){
        //注:LinkedHashMap是有序的
        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<>();

        filterChainDefinitionMap.put("/s/login.jsp", "anon");
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/s/permission.jsp", "perms[user:index]");
        filterChainDefinitionMap.put("/depts/index", "perms[depts:index]");
        filterChainDefinitionMap.put("/**", "authc");

        return filterChainDefinitionMap;
    }
}

 

 

今日重點 : 對securityManage 對象的獲取,在權限認證步驟中須要的信息傳遞(用戶,角色,權限)

細節 : 對於在設置權限列表時須要注意順序,-----放行在前->權限在後->最後同一攔截  /** = authc

相關文章
相關標籤/搜索