1. 程式人生 > 實用技巧 >shiro安全框架

shiro安全框架

1.SsSM框架整合shiro(基於ssm框架環境無誤的情況下)

  1.1.匯入約束

<properties> <shiro.version>1.2.3</shiro.version> </properties> <!-- shiro --> <!-- shiro核心包 --> <!-- 新增shiro web支援 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>${shiro.version}</version> </dependency> <!-- 新增shiro spring整合 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>${shiro.version}</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-all</artifactId> <version>1.2.3</version> </dependency>

  1.2.在web.xml中配置過濾器

 <!-- shiro框架過濾器-->
    <filter>
        <filter-name>delegatingFilterProxy</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>delegatingFilterProxy</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

  1.3.配置spring的配置檔案applicationContext.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" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 第一步配置ShiroFilterFactoryBean--> <!-- 要求id跟web.xml配置的過濾器id一樣--> <bean id="delegatingFilterProxy" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!--登入頁面--> <property name="loginUrl" value="/login.jsp"></property> <!--登入成功頁面--> <property name="successUrl" value="/succes.jsp"></property> <!--無許可權頁面--> <property name="unauthorizedUrl" value="unauthorized.jsp"></property> <!--安全管理器--> <property name="securityManager" ref="SecurityManager"></property> <!-- 那些路徑的訪問許可權--> <property name="filterChainDefinitions"> <value> <!-- 按順序賦予--> /login.jsp=anon <!-- anon無需認證--> /login/login=anon /chearuser=logout<!-- logout清除快取--> /admin.jsp=roles[admin]<!-- 需要admin這個許可權--> /user.jsp=roles[user] /**=authc<!-- 需要登入--> </value> </property> <!--<property name="filterChainDefinitionMap" ref="map">--> <!--</property>--> </bean> <!-- 安全管理器--> <bean id="SecurityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <!--<property name="authenticator" ref="ModularRealmAuthenticatorr"/>--> <!-- 需要自定義一個Realm--> <property name="realm" ref="MyRealm"></property> </bean> <!--自定義一個Realm --> <bean id="MyRealm" class="cwd.Shiro.MyRealm"> <!-- 加密證書匹配器--> <property name="credentialsMatcher"> <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <!-- 加密方法--> <property name="hashAlgorithmName" value="MD5"></property> <!-- 加密迭代的次數--> <property name="hashIterations" value="10"></property> </bean> </property> </bean> </beans>

  1.4.自定義一個Realm類  

package cwd.Shiro;
import cwd.Pojo.PersonalPojo;
import cwd.Service.PersonalService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.HashSet;
import java.util.Set;

public class MyRealm extends AuthorizingRealm {
    @Autowired
    private PersonalService service;
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //強轉取得控制層傳過來的UsernamePasswordToken
        UsernamePasswordToken token= (UsernamePasswordToken) authenticationToken;
        //獲取賬號
        String zhanghao= token.getUsername();
        //獲取realmname
        String realmname=getName();
        //加密的鹽值
        ByteSource salt=ByteSource.Util.bytes(zhanghao);
        //根據賬號去資料庫查詢
        PersonalPojo personal=service.findbyzhanghao(zhanghao);
        if (personal==null){
           throw new UnknownAccountException();
        }
        // 返回
        SimpleAuthenticationInfo simpleAuthenticationInfo=new SimpleAuthenticationInfo(zhanghao,personal.getMima(),salt,realmname);
        return simpleAuthenticationInfo;

    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //獲取賬號
        String  zhanghao= (String) principalCollection.getPrimaryPrincipal();
        PersonalPojo personal=service.findbyzhanghao(zhanghao);
        Set<String> roles=new HashSet<>();
        roles.add(personal.getQuanxian());
        if ("admin".equals(personal.getQuanxian())){
            roles.add("user");
        }
        //設定許可權
        SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo(roles);
        return simpleAuthorizationInfo;
    }
}

  1.5.Controller處理登入

package cwd.Controller;

import cwd.Pojo.PersonalPojo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/login")
public class LoginController {
    @RequestMapping("/login")
    public String login(PersonalPojo pojo) {
        //獲取subject物件
        Subject subject= SecurityUtils.getSubject();
        if (!subject.isAuthenticated()){
            //封裝一個UsernamePasswordToken物件
            UsernamePasswordToken token=new UsernamePasswordToken(pojo.getZhanghao(),pojo.getMima());
            //記住密碼
            token.setRememberMe(true);
            //登入方法
                subject.login(token);
        }
        return "redirect:/succes.jsp";
    }
}

1.2加密

1.2.1在備註配置realm的bean的時候,新增加密方法

 <!--自定義一個Realm -->
    <bean id="MyRealm" class="cwd.Shiro.MyRealm">
        <!-- 加密證書匹配器-->
        <property name="credentialsMatcher">
            <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                <!-- 加密方法-->
                <property name="hashAlgorithmName" value="MD5"></property>
                <!-- 加密迭代的次數-->
                <property name="hashIterations" value="10"></property>
            </bean>
        </property>
    </bean>

1.2.2獲取某數字的md5序列

 public static void main(String[] args) {
        //獲取 123  MD5的 迭代10次的數列
       Object object=new SimpleHash("MD5","123",null,10);
        System.out.println(object);
    }

1.2.3鹽值加密,達到即使兩個密碼相同,序列也不一樣

      String realmname=getName();
        //加密的鹽值
        ByteSource salt=ByteSource.Util.bytes(zhanghao);
        //根據賬號去資料庫查詢
        PersonalPojo personal=service.findbyzhanghao(zhanghao);
        if (personal==null){
           throw new UnknownAccountException();
        }
        // 返回
        SimpleAuthenticationInfo simpleAuthenticationInfo=new SimpleAuthenticationInfo(zhanghao,personal.getMima(),salt,realmname);

1.3多realms驗證

1.3.1配置多個reamls bean 一個是md5加密 一個是sha1加密

 <bean id="MyRealm" class="cwd.Shiro.MyRealm">
        <!-- 加密證書匹配器-->
        <property name="credentialsMatcher">
            <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                <!-- 加密方法-->
                <property name="hashAlgorithmName" value="MD5"></property>
                <!-- 加密迭代的次數-->
                <property name="hashIterations" value="10"></property>
            </bean>
        </property>
    </bean>
    <bean id="MeRealm" class="cwd.Shiro.MeRealm">
        <!-- 加密-->
        <property name="credentialsMatcher">
            <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                <property name="hashAlgorithmName" value="SHA1"></property>
                <property name="hashIterations" value="10"></property>
            </bean>
        </property>
    </bean>

1.3.2配置認證器

 <!-- 認證器-->
    <bean id="ModularRealmAuthenticatorr" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
        <property name="realms">
            <list>
                <ref bean="MyRealm"></ref>
                <ref bean="MeRealm"></ref>
            </list>
        </property>
        <!-- 開啟認證策略,都符合才通過,預設是一個通過就可以-->
        <property name="authenticationStrategy">
            <bean class="org.apache.shiro.authc.pam.AllSuccessfulStrategy"></bean>
        </property>
    </bean>

1.3.3註冊認證器

 <!-- 安全管理器-->
    <bean id="SecurityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
   
       <!--註冊認證器 -->
        <property name="authenticator" ref="ModularRealmAuthenticatorr"></property>
    </bean>

<!-- 安全管理器-->
<bean id="SecurityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!--<property name="authenticator" ref="ModularRealmAuthenticatorr"/>-->
<!-- 需要自定義一個Realm-->
<property name="realm" ref="MyRealm"></property>
<property name="authenticator" ref="ModularRealmAuthenticatorr"></property>
</bean>