springmvc集成shiro例子


僅供參考

僅供參考

登錄部分

代碼:

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> login(HttpServletRequest request)
    {
        Map<String, Object> resultMap = new LinkedHashMap<String, Object>();
        try
        {
            ShiroToken token = new ShiroToken("admin", "21232f297a57a5a743894a0e4a801fc3");
            token.setRememberMe(false);
            SecurityUtils.getSubject().login(token);
            ShiroToken token2 = (ShiroToken) SecurityUtils.getSubject().getPrincipal();

            logger.info(token2.getUsername() + "," + token2.getPswd());

            resultMap.put("status", 200);
            resultMap.put("message", "登錄成功");

            /**
             * 獲取登錄之前的地址
             */
            SavedRequest savedRequest = WebUtils.getSavedRequest(request);
            String url = null;
            if (null != savedRequest)
            {
                url = savedRequest.getRequestUrl();
            }
            // 跳轉地址
            resultMap.put("back_url", url);
        }
        catch (DisabledAccountException e)
        {
            resultMap.put("status", 500);
            resultMap.put("message", "帳號已經禁用。");
        }
        catch (Exception e)
        {
            resultMap.put("status", 500);
            resultMap.put("message", "帳號或密碼錯誤");
        }
        return resultMap;
    }

注意幾點:

1、登錄密碼記得加密,一般存在數據庫中的密碼是加密過的。

2、真正開始執行登錄操作的是SecurityUtils.getSubject().login(token),這個方法會調用org.apache.shiro.realm.AuthorizingRealm的doGetAuthenticationInfo方法進行登錄認證:

3、出錯異常記得捕獲

登錄驗證部分

代碼如下:

   @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0)
    {
        ShiroToken token = (ShiroToken) arg0;
        String username = token.getUsername();

        // 根據username從數據庫查找用戶,得到密碼
        // 假設找到的用戶如下
        // User user = userService.findByUsername(username)
        User user = new User();
        user.setName(username);
        user.setPassword("21232f297a57a5a743894a0e4a801fc3"); // 數據庫中的密碼md5加密的

        if (null == user)
        {
            throw new AccountException("username is not exist");
        }
        else if (!user.getPassword().equals(token.getPswd()))
        {
            throw new AccountException("password is not right");
        }
        else
        {
            // 登陸成功
            logger.info("{} login success.", username);
        }
        return new SimpleAuthenticationInfo(arg0, user.getPassword(), username);
    }

注意幾點:

1、一般會根據username從數據庫中查找該用戶,得到密碼

2、進行密碼校驗,判斷一致性

3、根據獲取到的用戶信息,也可以進行其它判斷,如用戶是否激活,是否被禁用等

授權部分

代碼如下:

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0)
    {
        ShiroToken token = (ShiroToken) SecurityUtils.getSubject().getPrincipal();
        String username = token.getUsername();
        logger.info(username + "授權...");

        // 從數據庫中查找該用戶的角色和權限
        SimpleAuthorizationInfo sainfo = new SimpleAuthorizationInfo();

        Set<String> roles = new HashSet<String>();
        roles.add("admin");
        //roles.add("role1");
        Set<String> permissions = new HashSet<String>();
        permissions.add("add");
        permissions.add("delete");
        sainfo.setRoles(roles);
        sainfo.setStringPermissions(permissions);
        return sainfo;
    }

注意,一般是根據用戶名從數據庫中查找該用戶的角色和權限,進行授權;當然其它途徑也是可以的,如webservice接口,配置文件等獲取用戶權限。

權限攔截配置

如下:

    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"></property>
        <property name="loginUrl" value="/security/view/login"></property>
        <property name="successUrl" value="/successUrl"></property>
        <!-- 用戶訪問未對其授權的資源時,所顯示的連接 -->
        <property name="unauthorizedUrl" value="/unauthorizedUrl"></property>
        <property name="filters">
            <map>
                <entry key="anyRoles">
                    <bean class="cn.edu.hdu.ssd.core.shiro.AnyRolesAuthorizationFilter" />
                </entry>
            </map>
        </property>
        <property name="filterChainDefinitions">
            <value>
                /security/**=anon
                /test/**=roles[role1]
                /users/**=anyRoles[admin,role1]
                /**=authc
            </value>
        </property>
    </bean>

根據用戶的角色或權限來配置對應匹配的訪問路徑;

訪問路徑匹配任意角色

默認情況下,配置權限控制的時候,如

/test/**=roles[role1,admin]

結果是需要用戶同時擁有role1和admin權限才能訪問/test/**路徑,這往往不符合我們的需求,

大部分情況,我們希望的是用戶擁有role1和admin任一角色即可。

那么可以這樣修改,編寫一個過濾器:

public class AnyRolesAuthorizationFilter extends AuthorizationFilter
{

    // private Logger logger =  LoggerFactory.getLogger(ShiroCasAuthFilter.class);
    @Override
    protected boolean isAccessAllowed(ServletRequest req, ServletResponse resp, Object mappedValue)
        throws Exception
    {
        Subject subject = getSubject(req, resp);
        String[] rolesArray = (String[]) mappedValue;

        if (rolesArray == null || rolesArray.length == 0)
        {
            return true;
        }
        for (int i = 0; i < rolesArray.length; i++)
        {
            if (subject.hasRole(rolesArray[i]))
            {
                return true;
            }
        }
        return false;
    }
}

配置shiroFilter bean的filters屬性,如下,

        <property name="filters">
            <map>
                <entry key="anyRoles">
                    <bean class="cn.edu.hdu.ssd.core.shiro.AnyRolesAuthorizationFilter" />
                </entry>
            </map>
        </property>

最后,權限攔截配置可以這樣配:

/test/**=anyRoles[admin,role1]

示例源碼參考

https://github.com/peterchenhdu/spring-shiro-demo

測試

登錄:http://localhost:8080/ssd/security/login ----->角色:admin,用戶名:admin,密碼:21232f297a57a5a743894a0e4a801fc3
權限測試:http://localhost:8080/ssd/users ----->訪問成功
權限測試:http://localhost:8080/ssd/test/access ----->訪問失敗,無訪問權限
換個角色登錄,修改UserRealm.java里的角色為roler1,重新登錄http://localhost:8080/ssd/security/login
權限測試:http://localhost:8080/ssd/users ----->訪問成功
權限測試:http://localhost:8080/ssd/test/access ----->訪問成功


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM