springboot + jwt + shiro 前后端分離權(quán)限框架

權(quán)限類說明:

權(quán)限配置類:ShiroConfiguration (權(quán)限核心配置類)叽讳、AuthFilter(攔截器配置類)、AuthRealm(認證類)蝠咆、AuthTokenVo冰更、NoPermissionException(無權(quán)限異常處理類)、JWTUtil(token工具類)贱勃、AuthConstant(提示類)井赌、ReturnMessage 返回信息類
測試需要的類:User UserController UserList UserPermission UserRole
maven坐標

權(quán)限核心配置

import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @ClassName ShiroConfiguration
 * @Description
 * @Author XinChunYu
 * @Date 2020/5/29 13:42
 * @Version 1.0
 **/
@Configuration
public class ShiroConfiguration {

    private org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(ShiroConfiguration.class);

    //從配置文件里面讀取是否需要啟動登錄認證的開關,默認true
    //@Value("${jwt.auth}")
    private boolean auth = true;

    //配置攔截器
    @Bean
    public ShiroFilterFactoryBean shiroFilter(org.apache.shiro.mgt.SecurityManager securityManager) {

        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //設置securityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //啟用認證
        String openAuth = auth ? "auth" : "anon";

        //自定義過濾器鏈
        Map<String, javax.servlet.Filter> filters = new HashMap<>();
        //指定攔截器處理
        filters.put("auth", new com.lzqs.yuanzilian.shiro.AuthFilter());
        shiroFilterFactoryBean.setFilters(filters);
        Map<String, String> filterMap = new LinkedHashMap<>();

        //登錄請求不攔截
        filterMap.put("/user/login", "anon");
        //登錄頁面需要用到的接口仇穗,不攔截
        filterMap.put("/user/fetchCurrentUser", "anon");
        //攔截所有接口請求戚绕,做權(quán)限判斷
        filterMap.put("/**", openAuth);

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
        logger.info("Shiro攔截器工廠類注入成功");
        return shiroFilterFactoryBean;
    }

    // SecurityManager 安全管理器;Shiro的核心
    @Bean
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(userRealm());
        return securityManager;
    }

    //自定義身份認證realm
    @Bean
    public AuthRealm userRealm() {
        return new AuthRealm();
    }

    @Bean("lifecycleBeanPostProcessor")
    //管理shiro生命周期
    public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    //Shiro注解支持
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(org.apache.shiro.mgt.SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager((org.apache.shiro.mgt.SecurityManager) securityManager);
        return authorizationAttributeSourceAdvisor;
    }

}

權(quán)限過濾器

package com.lzqs.yuanzilian.shiro;

import com.alibaba.fastjson.JSONObject;
import com.lzqs.yuanzilian.constant.ReturnMessage;
import com.lzqs.yuanzilian.shiro.util.AuthConstant;
import com.lzqs.yuanzilian.shiro.util.JWTUtil;
import io.micrometer.core.instrument.util.StringUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.web.filter.authc.AuthenticatingFilter;
import org.apache.shiro.web.util.WebUtils;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @ClassName AuthFilter
 * @Description 實現(xiàn)自定義的認證攔截器,接收傳過來的token,實現(xiàn)前后端分離的權(quán)限認證
 * @Author XinChunYu
 * @Date 2020/5/29 14:03
 * @Version 1.0
 **/
public class AuthFilter extends AuthenticatingFilter {

    private org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(AuthorizingRealm.class);
    private ReturnMessage responseResult = ReturnMessage.failWithMsg(AuthConstant.AUTHENTICATE_FAIL);

        @Override
        protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception {
            return null;
        }

        /**
         * 在這里攔截所有請求
         * @param request
         * @param response
         * @param mappedValue
         * @return
         */
        @Override
        protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
            String token = JWTUtil.getRequestToken((HttpServletRequest)request);
            if (!StringUtils.isBlank(token)){
                try {
                    this.executeLogin(request, response);
                } catch (Exception e) {
                    // 應用異常
                    logger.info(e.getMessage());
                    responseResult = ReturnMessage.failWithMsg(e.getMessage());
                    return false;
                }
            } else {
                // cookie中未檢查到token或token為空
                HttpServletRequest httpServletRequest = WebUtils.toHttp(request);
                String httpMethod = httpServletRequest.getMethod();
                String requestURI = httpServletRequest.getRequestURI();
                responseResult = ReturnMessage.failWithMsg(AuthConstant.TOKEN_BLANK);
                logger.info("請求 {} 的Token為空 請求類型 {}", requestURI, httpMethod);
                return false;
            }
            return true;
        }

        /**
         * 請求失敗攔截,請求終止,不進行轉(zhuǎn)發(fā)直接返回客戶端攔截結(jié)果
         * @param request
         * @param response
         * @return
         * @throws Exception
         */
        @Override
        protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception{
            HttpServletResponse httpServletResponse = (HttpServletResponse)response;
            httpServletResponse.setContentType("application/json; charset=utf-8");
            httpServletResponse.setCharacterEncoding("UTF-8");
            //ReturnMessage returnMessage = ReturnMessage.failWithMsg(AuthConstant.AUTHENTICATE_FAIL);
            httpServletResponse.getWriter().print(JSONObject.toJSONString(responseResult));
            return false;
        }

        /**
         * 用戶存在谷誓,執(zhí)行登錄認證
         * @param request
         * @param response
         * @return
         * @throws Exception
         */
        @Override
        protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
            String token = JWTUtil.getRequestToken((HttpServletRequest)request);
            AuthTokenVo jwtToken = new AuthTokenVo(token);
            // 提交給AuthRealm進行登錄認證
            getSubject(request, response).login(jwtToken);
            return true;
        }
}

token認證和權(quán)限認證

import com.lzqs.yuanzilian.shiro.controller.User;
import com.lzqs.yuanzilian.shiro.controller.UserList;
import com.lzqs.yuanzilian.shiro.controller.UserPermission;
import com.lzqs.yuanzilian.shiro.controller.UserRole;
import com.lzqs.yuanzilian.shiro.util.AuthConstant;
import io.micrometer.core.instrument.util.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

/**
 * @ClassName AuthRealm
 * @Description
 * @Author XinChunYu
 * @Date 2020/5/29 13:51
 * @Version 1.0
 **/
public class AuthRealm extends AuthorizingRealm {

    private org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(AuthorizingRealm.class);

    /**
     * 重寫懊烤,繞過身份令牌異常導致的shiro報錯
     * @param authenticationToken
     * @return
     */
    @Override
    public boolean supports(AuthenticationToken authenticationToken){
        return authenticationToken instanceof AuthTokenVo;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        logger.info("用戶角色權(quán)限認證");
        //獲取用戶登錄信息
        User user = (User)principals.getPrimaryPrincipal();
        //添加角色和權(quán)限
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        for(UserRole userRole : user.getUserRoleList()){
            authorizationInfo.addRole(userRole.getUserRoleName());
            for(UserPermission permissionVo : userRole.getUserPermissionList()){
                authorizationInfo.addStringPermission(permissionVo.getUserPermissionName());
            }
        }
        return authorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        logger.info("執(zhí)行認證邏輯");
        //獲得token
        String token = (String)authenticationToken.getCredentials();
        //獲得token中的用戶信息
        String username = JwtAuthenticator.getUsername(token);
        //判空
        if(StringUtils.isBlank(username)){
            throw new AuthenticationException(AuthConstant.TOKEN_BLANK);
        }
        User user = null;
        try{
            for(User u : UserList.userList){
                if(u.getUsername().equals(username)){
                    user = u;
                }
            }
            //查詢用戶是否存在
            if(user == null){
                throw new AuthenticationException(AuthConstant.TOKEN_INVALID);
                //token過期
            }else if(!(JwtAuthenticator.verifyToken(token, username, user.getPassword()))){
                throw new AuthenticationException(AuthConstant.TOKEN_EXPIRE);
            }
        }catch (Exception e){
            throw e;
        }
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                user,
                token,
                getName());
        return authenticationInfo;
    }
}

jwt token對象

import org.apache.shiro.authc.AuthenticationToken;

/**
 * @ClassName AuthTokenVo
 * @Description
 * @Author XinChunYu
 * @Date 2020/5/29 14:09
 * @Version 1.0
 **/
public class AuthTokenVo implements AuthenticationToken {
    private String token;
    public AuthTokenVo(String token){
        this.token = token;
    }

    @Override
    public Object getPrincipal(){
        return token;
    }

    @Override
    public Object getCredentials(){
        return token;
    }
}

異常處理

import com.alibaba.fastjson.JSONObject;
import com.lzqs.yuanzilian.constant.ReturnMessage;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @ClassName NoPermissionException
 * @Description
 * @Author XinChunYu
 * @Date 2020/5/30 15:12
 * @Version 1.0
 **/
@ControllerAdvice
public class NoPermissionException {

    /**
     * 用戶角色權(quán)限認證 當沒有權(quán)限時會報UnauthorizedException異常 此處處理異常給前端返回提示語
     * @param response
     * @param ex
     * @throws IOException
     */
    @ResponseBody
    @ExceptionHandler(UnauthorizedException.class)
    public void handleShiroException(HttpServletResponse response, Exception ex) throws IOException {
        HttpServletResponse httpServletResponse = (HttpServletResponse)response;
        httpServletResponse.setContentType("application/json; charset=utf-8");
        httpServletResponse.setCharacterEncoding("UTF-8");
        //ReturnMessage returnMessage = ReturnMessage.failWithMsg(AuthConstant.AUTHENTICATE_FAIL);
        httpServletResponse.getWriter().print(JSONObject.toJSONString(ReturnMessage.failWithMsg("訪問了無權(quán)限目錄")));
    }
   //執(zhí)行認證邏輯認證不通過時會走  過濾器AuthFilter中的onAccessDenied方法 所以這個異常不捕獲
   /* @ResponseBody
    @ExceptionHandler(AuthorizationException.class)
    public String AuthorizationException(Exception ex) {
        return "權(quán)限認證失敗";
    }*/
}

jwt token工具類

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.Date;

/**
 * @ClassName JWTUtil
 * @Description
 * @Author XinChunYu
 * @Date 2020/5/29 13:18
 * @Version 1.0
 **/
public class JWTUtil {

    // 過期時間50分鐘
    private static final long EXPIRE_TIME = 50*60*1000;

    /**
     * 校驗token是否正確
     * @param token 密鑰
     * @param secret 用戶的密碼
     * @return 是否正確
     */
    public static boolean verify(String token, String username, String secret) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(secret);
            JWTVerifier verifier = JWT.require(algorithm)
                    .withClaim("username", username)
                    .build();
            DecodedJWT jwt = verifier.verify(token);
            return true;
        } catch (Exception exception) {
            return false;
        }
    }

    /**
     * 獲得token中的信息無需secret解密也能獲得
     * @return token中包含的用戶名
     */
    public static String getUsername(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("username").asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 生成簽名,5min后過期
     * @param username 用戶名
     * @param secret 用戶的密碼
     * @return 加密的token
     */
    public static String sign(String username, String secret) {
        try {
            Date date = new Date(System.currentTimeMillis()+EXPIRE_TIME);
            Algorithm algorithm = Algorithm.HMAC256(secret);
            // 附帶username信息
            return JWT.create()
                    .withClaim("username", username)
                    .withExpiresAt(date)
                    .sign(algorithm);
        } catch (UnsupportedEncodingException e) {
            return null;
        }
    }

    public static String getRequestToken(HttpServletRequest request) {
        return request.getHeader("token");
    }
}

認證提示

package com.lzqs.yuanzilian.shiro.util;

/**
 * @ClassName AuthConstant
 * @Description 權(quán)限相關的常量
 * @Author XinChunYu
 * @Date 2020/5/29 14:06
 * @Version 1.0
 **/
public class AuthConstant {

        /**
         * cookie中存儲的token字段名
         */
        public final static String COOKIE_TOKEN_NAME = "Authorization";

        /**
         * token有效時間 時*分*秒*1000L
         */
        public final static Long EXPIRE_TIME = 3*60*1000L;//先設置3分鐘

        //登錄認證結(jié)果,返回給前端
        public final static String UNKNOWN_ACCOUNT = "登錄失敗, 用戶不存在。";

        public final static String WRONG_PASSWORD = "登錄失敗糙臼,密碼錯誤。";

        public final static String TOKEN_BLANK = "驗證失敗蒋伦,token為空弓摘,請登錄。";

        public final static String TOKEN_INVALID = "驗證失敗痕届,token錯誤韧献。";

        public final static String TOKEN_EXPIRE = "驗證失敗,token過期研叫,請重新登錄锤窑。";

        public final static String AUTHENTICATE_FAIL = "無訪問權(quán)限,請嘗試登錄或聯(lián)系管理員嚷炉。";
}

ReturnMessage返回提示類

package com.lzqs.yuanzilian.constant;

import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 通用的返回類
 **/
public class ReturnMessage implements Serializable {
    //狀態(tài)碼 100-成功渊啰,200-失敗 400-帶信息失敗
    private int code;
    //提示信息
    private String msg;
    //用戶要返回給瀏覽器的數(shù)據(jù)
    private Map<String, Object> data = new LinkedHashMap<>();

    public static ReturnMessage successWithData(Map<String, Object> data) {
        ReturnMessage result = new ReturnMessage();
        result.setCode(100);
        result.setMsg("成功");
        result.setData(data);
        return result;
    }

    public static ReturnMessage success() {
        ReturnMessage result = new ReturnMessage();
        result.setCode(100);
        result.setMsg("成功");
        return result;
    }

    public static ReturnMessage successWithMsg(String newmsg){
        ReturnMessage result = new ReturnMessage();
        result.setCode(100);
        result.setMsg(newmsg);
        return result;
    }

    public static ReturnMessage fail() {
        ReturnMessage result = new ReturnMessage();
        result.setCode(200);
        result.setMsg("系統(tǒng)錯誤");
        return result;
    }

    public static ReturnMessage failWithMsg(String newmsg) {
        ReturnMessage result = new ReturnMessage();
        result.setCode(400);
        result.setMsg(newmsg);
        return result;
    }


    /**
     * 失敗 + 自定義msg,缺省為"處理失敗"
     *
     * @param newmsg
     * @return
     */
    public static ReturnMessage failWithMsg(int code, String newmsg) {
        ReturnMessage result = new ReturnMessage();
        result.setCode(code);
        if (StringUtils.isEmpty(newmsg)) {
            newmsg = "處理失敗";
        }
        result.setMsg(newmsg);
        return result;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Map<String, Object> getData() {
        return data;
    }

    public void setData(Map<String, Object> data) {
        this.data = data;
    }

    public ReturnMessage add(String key, Object value) {
        this.getData().put(key, value);
        return this;
    }
}

controller控制器

import com.lzqs.yuanzilian.constant.ReturnMessage;
import com.lzqs.yuanzilian.shiro.util.AuthConstant;
import com.lzqs.yuanzilian.shiro.util.JWTUtil;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Map;

/**
 * @ClassName UserController
 * @Description
 * @Author XinChunYu
 * @Date 2020/5/29 14:15
 * @Version 1.0
 **/
@Controller
@RequestMapping("/user")
public class UserController {


    @RequestMapping("/login")
    @ResponseBody
    public ReturnMessage login(@RequestBody Map<String, Object> map){
        String username = map.get("username").toString();
        String password = map.get("password").toString();
        User user = null;
        for(User u : UserList.userList){
            if(u.getUsername().equals(username)){
                user = u;
            }
        }
        if(user == null){
            //賬號不存在
            return ReturnMessage.failWithMsg(AuthConstant.UNKNOWN_ACCOUNT);
        }else if(!user.getPassword().equals(password)){
            //密碼錯誤
            return ReturnMessage.failWithMsg(AuthConstant.WRONG_PASSWORD);
        }else{
            //通過認證, 生成簽名
            String token = JWTUtil.sign(user.getUsername(), user.getPassword());
            return ReturnMessage.success().add("token", token);
        }
    }


    @RequiresPermissions("shop")
    @RequestMapping("/shop")
    @ResponseBody
    public ReturnMessage shop(@RequestBody Map<String, Object> map){

            return ReturnMessage.success();
    }

    @RequiresPermissions("order")
    @RequestMapping("/order")
    @ResponseBody
    public ReturnMessage order(@RequestBody Map<String, Object> map){

        return ReturnMessage.success();
    }

    /**
     * 不加@RequiresPermissions 注解時不會進行用戶授權(quán)認證
     * @param map
     * @return
     */
    @RequestMapping("/game")
    @ResponseBody
    public ReturnMessage game(@RequestBody Map<String, Object> map){
        return ReturnMessage.success();
    }

    @RequestMapping("/address")
    @ResponseBody
    public ReturnMessage address(@RequestBody Map<String, Object> map){
        return ReturnMessage.success();
    }
}

用戶類

package com.lzqs.yuanzilian.shiro.controller;

import java.util.List;

/**
 * @ClassName UserBean
 * @Description 用戶表
 * @Author XinChunYu
 * @Date 2020/5/29 13:16
 * @Version 1.0
 **/
public class User {
    private Long userId;
    private String username;
    private String password;
    private String salt;//鹽值
    private List<UserRole> userRoleList;

    public User() {
    }

    public User(Long userId, String username, String password, String salt, List<UserRole> userRoleList) {
        this.userId = userId;
        this.username = username;
        this.password = password;
        this.salt = salt;
        this.userRoleList = userRoleList;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public List<UserRole> getUserRoleList() {
        return userRoleList;
    }

    public void setUserRoleList(List<UserRole> userRoleList) {
        this.userRoleList = userRoleList;
    }

    public String getSalt() {
        return salt;
    }

    public void setSalt(String salt) {
        this.salt = salt;
    }
}

角色類

package com.lzqs.yuanzilian.shiro.controller;

import java.util.List;

/**
 * @ClassName UserRole
 * @Description 角色表
 * @Author XinChunYu
 * @Date 2020/5/29 13:34
 * @Version 1.0
 **/
public class UserRole {
    private Long userRoleId;
    private String userRoleName;
    List<UserPermission> userPermissionList;

    public UserRole(Long userRoleId, String userRoleName, List userPermissionList) {
        this.userRoleId = userRoleId;
        this.userRoleName = userRoleName;
        this.userPermissionList = userPermissionList;
    }

    public Long getUserRoleId() {
        return userRoleId;
    }

    public void setUserRoleId(Long userRoleId) {
        this.userRoleId = userRoleId;
    }

    public String getUserRoleName() {
        return userRoleName;
    }

    public void setUserRoleName(String userRoleName) {
        this.userRoleName = userRoleName;
    }

    public List<UserPermission> getUserPermissionList() {
        return userPermissionList;
    }

    public void setUserPermissionList(List<UserPermission> userPermissionList) {
        this.userPermissionList = userPermissionList;
    }
}

權(quán)限

package com.lzqs.yuanzilian.shiro.controller;

/**
 * @ClassName Permission
 * @Description 權(quán)限表
 * @Author XinChunYu
 * @Date 2020/5/29 13:35
 * @Version 1.0
 **/
public class UserPermission {
    private Long userPermissionId;
    private String userPermissionName;

    public UserPermission(Long userPermissionId, String userPermissionName) {
        this.userPermissionId = userPermissionId;
        this.userPermissionName = userPermissionName;
    }

    public Long getUserPermissionId() {
        return userPermissionId;
    }

    public void setUserPermissionId(Long userPermissionId) {
        this.userPermissionId = userPermissionId;
    }

    public String getUserPermissionName() {
        return userPermissionName;
    }

    public void setUserPermissionName(String userPermissionName) {
        this.userPermissionName = userPermissionName;
    }
}

用戶集合在這就不建表查數(shù)據(jù)庫了

package com.lzqs.yuanzilian.shiro.controller;

import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName UserList
 * @Description
 * @Author XinChunYu
 * @Date 2020/5/29 16:15
 * @Version 1.0
 **/
public class UserList {

    public static List<User> userList = new ArrayList<>();
    static{
        ArrayList<UserPermission> userPermissionArrayList1 = new ArrayList<>();
        userPermissionArrayList1.add(new UserPermission(1l,"shop"));
        userPermissionArrayList1.add(new UserPermission(2l,"game"));
        userPermissionArrayList1.add(new UserPermission(1l,"order"));
        userPermissionArrayList1.add(new UserPermission(1l,"address"));
        ArrayList<UserRole> userRoleArrayList1 = new ArrayList<>();
        userRoleArrayList1.add(new UserRole(1L, "老板", userPermissionArrayList1));
        User user1 = new User(1l, "admin", "123456", "iwejfiwjf", userRoleArrayList1);

        ArrayList<UserPermission> userPermissionArrayList2 = new ArrayList<>();
        userPermissionArrayList2.add(new UserPermission(1l,"shop"));
        userPermissionArrayList2.add(new UserPermission(2l,"game"));
        ArrayList<UserRole> userRoleArrayList2 = new ArrayList<>();
        userRoleArrayList2.add(new UserRole(2L, "經(jīng)理", userPermissionArrayList2));
        User user2 = new User(2l, "xiaoming", "123456", "jfiosjfos", userRoleArrayList2);

        userList.add(user1);
        userList.add(user2);
    }
}

maven坐標

        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.7.0</version>
        </dependency>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子绘证,更是在濱河造成了極大的恐慌隧膏,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嚷那,死亡現(xiàn)場離奇詭異胞枕,居然都是意外死亡,警方通過查閱死者的電腦和手機魏宽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門腐泻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人队询,你說我怎么就攤上這事派桩。” “怎么了蚌斩?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵铆惑,是天一觀的道長鸭津。 經(jīng)常有香客問我逆趋,道長闻书,這世上最難降的妖魔是什么脑慧? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任坑律,我火速辦了婚禮晃择,結(jié)果婚禮上宫屠,老公的妹妹穿的比我還像新娘滑蚯。我一直安慰自己,他們只是感情好古劲,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布绢慢。 她就那樣靜靜地躺著,像睡著了一般骚露。 火紅的嫁衣襯著肌膚如雪棘幸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天吨悍,我揣著相機與錄音育瓜,去河邊找鬼躏仇。 笑死腺办,一個胖子當著我的面吹牛怀喉,可吹牛的內(nèi)容都是我干的躬拢。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼馅袁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起抵窒,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤李皇,失蹤者是張志新(化名)和其女友劉穎掉房,沒想到半個月后慰丛,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體诅病,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡蝇棉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年篡殷,在試婚紗的時候發(fā)現(xiàn)自己被綠了贴唇。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片戳气。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡瓶您,死狀恐怖呀袱,靈堂內(nèi)的尸體忽然破棺而出郑叠,到底是詐尸還是另有隱情乡革,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布嘁傀,位于F島的核電站,受9級特大地震影響橙凳,放射性物質(zhì)發(fā)生泄漏岛啸。R本人自食惡果不足惜茴肥,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望芬首。 院中可真熱鬧逼裆,春花似錦耀怜、人聲如沸桐愉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽描扯。三九已至绽诚,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間岔帽,已是汗流浹背导绷。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工贾费, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留褂萧,地道東北人导犹。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像羡忘,于是被迫代替她去往敵國和親谎痢。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345