1. 程式人生 > >008-shiro與spring web項目整合【二】認證、授權、session管理

008-shiro與spring web項目整合【二】認證、授權、session管理

添加 ner != efi ebs ref private date err

一、認證

1、添加憑證匹配器

添加憑證匹配器實現md5加密校驗。

修改applicationContext-shiro.xml:

技術分享
    <!-- realm -->
    <bean id="customRealm" class="com.lhx.ssm.shiro.CustomRealm">
        <!-- 將憑證匹配器設置到realm中,realm按照憑證匹配器的要求進行散列 -->
        <property name="credentialsMatcher" ref="credentialsMatcher"
/> </bean> <!-- 憑證匹配器 --> <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <property name="hashAlgorithmName" value="md5"/> <property name="hashIterations" value="1"/> </
bean>
View Code

2、修改realm認證方法

修改realm代碼從數據庫中查詢用戶身份信息,將sysService註入realm。

技術分享
public class CustomRealm extends AuthorizingRealm {
    
    //註入service
    @Autowired
    private SysService sysService;

    // 設置realm的名稱
    @Override
    public void setName(String name) {
        super.setName("customRealm");
    }
    
// 支持什麽類型的token @Override public boolean supports(AuthenticationToken token) { return token instanceof UsernamePasswordToken; } // 用於認證 //realm的認證方法,從數據庫查詢用戶信息 @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token) throws AuthenticationException { // token是用戶輸入的用戶名和密碼 // 第一步從token中取出用戶名 String userCode = (String) token.getPrincipal(); // 第二步:根據用戶輸入的userCode從數據庫查詢 SysUser sysUser = null; try { sysUser = sysService.findSysUserByUserCode(userCode); } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); } // 如果查詢不到返回null if(sysUser==null){// return null; } // 從數據庫查詢到密碼 String password = sysUser.getPassword(); // String salt = sysUser.getSalt(); // 如果查詢到返回認證信息AuthenticationInfo //activeUser就是用戶身份信息 ActiveUser activeUser = new ActiveUser(); activeUser.setUserid(sysUser.getId()); activeUser.setUsercode(sysUser.getUsercode()); activeUser.setUsername(sysUser.getUsername()); //.. //根據用戶id取出菜單 List<SysPermission> menus = null; try { //通過service取出菜單 menus = sysService.findMenuListByUserId(sysUser.getId()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } //將用戶菜單 設置到activeUser activeUser.setMenus(menus); //將activeUser設置simpleAuthenticationInfo SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo( activeUser, password,ByteSource.Util.bytes(salt), this.getName()); return simpleAuthenticationInfo; } // ……授權下一個 }
View Code

二、授權

1.修改realm授權方法

修改realm代碼從數據庫中查詢權限信息,將sysService註入realm

技術分享
public class CustomRealm extends AuthorizingRealm {
    
    //註入service
    @Autowired
    private SysService sysService;

    // 設置realm的名稱
    @Override
    public void setName(String name) {
        super.setName("customRealm");
    }
    // 支持什麽類型的token
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof UsernamePasswordToken;
    }

    // 用於認證    
    //realm的認證方法,從數據庫查詢用戶信息
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken token) throws AuthenticationException {
        
        // token是用戶輸入的用戶名和密碼 
        // 第一步從token中取出用戶名
        String userCode = (String) token.getPrincipal();

        // 第二步:根據用戶輸入的userCode從數據庫查詢
        SysUser sysUser = null;
        try {
            sysUser = sysService.findSysUserByUserCode(userCode);
        } catch (Exception e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        // 如果查詢不到返回null
        if(sysUser==null){//
            return null;
        }
        // 從數據庫查詢到密碼
        String password = sysUser.getPassword();
        
        //
        String salt = sysUser.getSalt();

        // 如果查詢到返回認證信息AuthenticationInfo
        
        //activeUser就是用戶身份信息
        ActiveUser activeUser = new ActiveUser();
        
        activeUser.setUserid(sysUser.getId());
        activeUser.setUsercode(sysUser.getUsercode());
        activeUser.setUsername(sysUser.getUsername());
        //..
        
        //根據用戶id取出菜單
        List<SysPermission> menus  = null;
        try {
            //通過service取出菜單 
            menus = sysService.findMenuListByUserId(sysUser.getId());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //將用戶菜單 設置到activeUser
        activeUser.setMenus(menus);

        //將activeUser設置simpleAuthenticationInfo
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
                activeUser, password,ByteSource.Util.bytes(salt), this.getName());

        return simpleAuthenticationInfo;
    }
    
    

    // 用於授權
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(
            PrincipalCollection principals) {
        
        //從 principals獲取主身份信息
        //將getPrimaryPrincipal方法返回值轉為真實身份類型(在上邊的doGetAuthenticationInfo認證通過填充到SimpleAuthenticationInfo中身份類型),
        ActiveUser activeUser =  (ActiveUser) principals.getPrimaryPrincipal();
        
        //根據身份信息獲取權限信息
        //從數據庫獲取到權限數據
        List<SysPermission> permissionList = null;
        try {
            permissionList = sysService.findPermissionListByUserId(activeUser.getUserid());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //單獨定一個集合對象 
        List<String> permissions = new ArrayList<String>();
        if(permissionList!=null){
            for(SysPermission sysPermission:permissionList){
                //將數據庫中的權限標簽 符放入集合
                permissions.add(sysPermission.getPercode());
            }
        }
        
        
    /*    List<String> permissions = new ArrayList<String>();
        permissions.add("user:create");//用戶的創建
        permissions.add("item:query");//商品查詢權限
        permissions.add("item:add");//商品添加權限
        permissions.add("item:edit");//商品修改權限
*/        //....
        
        //查到權限數據,返回授權信息(要包括 上邊的permissions)
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //將上邊查詢到授權信息填充到simpleAuthorizationInfo對象中
        simpleAuthorizationInfo.addStringPermissions(permissions);

        return simpleAuthorizationInfo;
    }    
}
View Code

2、對controller開啟aop

在springmvc.xml中配置shiro註解支持,可在controller方法中使用shiro註解配置權限:

    <!-- 開啟aop,對類代理 -->
    <aop:config proxy-target-class="true"></aop:config>
    <!-- 開啟shiro註解支持 -->
    <bean
        class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager" />
    </bean>

3、權限註解控制

商品查詢controller方法添加權限(item:query):

    // 查詢商品列表
    @RequestMapping("/queryItem")
    @RequiresPermissions("item:query")
    public ModelAndView queryItem() throws Exception {

上邊代碼@RequiresPermissions("item:query")表示必須擁有“item:query”權限方可執行。

同理,商品修改controller方法添加權限(item:update):

    @RequestMapping(value = "/editItem")
    @RequiresPermissions("item:update")
    public String editItem(@RequestParam(value = "id", required = true) Integer id, Model model) throws Exception

商品提交

    // 商品修改提交
    @RequestMapping("/editItemSubmit")
    @RequiresPermissions("item:update")
    public String editItemSubmit(@ModelAttribute("item") Items items,BindingResult result,MultipartFile pictureFile,Model model,HttpServletRequest request)
            throws Exception

4、jsp標簽控制

4.1、標簽簡介

a、Jsp頁面添加:

<%@ tagliburi="http://shiro.apache.org/tags" prefix="shiro" %>

b、詳細

標簽名稱

標簽條件(均是顯示標簽內容)

<shiro:authenticated>

登錄之後

<shiro:notAuthenticated>

不在登錄狀態時

<shiro:guest>

用戶在沒有RememberMe時

<shiro:user>

用戶在RememberMe時

<shiro:hasAnyRoles name="abc,123" >

在有abc或者123角色時

<shiro:hasRole name="abc">

擁有角色abc

<shiro:lacksRole name="abc">

沒有角色abc

<shiro:hasPermission name="abc">

擁有權限資源abc

<shiro:lacksPermission name="abc">

沒有abc權限資源

<shiro:principal>

顯示用戶身份名稱

<shiro:principal property="username"/> 顯示用戶身份中的屬性值

4.2、jsp頁面添加標簽

如果有商品修改權限頁面顯示“修改”鏈接。

<shiro:hasPermission name="item:update">
    <a href="${pageContext.request.contextPath }/item/editItem.action?id=${item.id}">修改</a>
</shiro:hasPermission>

三、session管理

和shiro整合後,使用shiro的session管理,shiro提供sessionDao操作 會話數據。

    <!-- securityManager安全管理器 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="customRealm"/>
        <!-- 註入session管理器 -->
        <property name="sessionManager" ref="sessionManager"/>
    </bean>
    <!-- 會話管理器 -->
    <bean id="sessionManager"          class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        <!-- session的失效時長,單位毫秒 -->
        <property name="globalSessionTimeout" value="600000"/>
        <!-- 刪除失效的session -->
        <property name="deleteInvalidSessions" value="true"/>
    </bean>

008-shiro與spring web項目整合【二】認證、授權、session管理