Shiro 项目开发中第一次使用到,所以研究了一下,这里

来源:互联网 发布:js 汽车360度全景系统 编辑:程序博客网 时间:2024/05/20 22:26

项目使用的是Maven 

首先要在pom.xml中引入shiro依赖

<!-- shiro 权限 --><dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-core</artifactId>    <version>${shiro.version}</version></dependency><dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-web</artifactId>    <version>${shiro.version}</version></dependency><dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-spring</artifactId>    <version>${shiro.version}</version></dependency><dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-aspectj</artifactId>    <version>${shiro.version}</version></dependency>

然后,在spring-mvc.xml 文件中配置 整合

<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"><!-- shiro 开启事务注解 -->    <property name="securityManager" ref="securityManager"></property></bean><bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><!-- shiro 安全管理器 -->    <property name="realm" ref="loginRealm"></property></bean><bean id="loginRealm" class="com.yxb.user.controller.LoginRealm"></bean><!-- 自定义 loginRealm    处理登陆具体业务dai--><!-- shiro 工厂bean配置 --><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">    <property name="securityManager" ref="securityManager"></property><!-- shiro的核心安全接口 -->    <property name="loginUrl" value="/common/login"></property><!-- 要求登录时的连接 -->    <!-- <property name="successUrl" value="/" ></property> --><!-- 登录成功后要跳转的连接(此处已经在登录中处理了) -->    <property name="unauthorizedUrl" value="/common/unauth"></property><!-- 未认证时要跳转的连接 -->    <!-- shiro连接约束配置 -->    <property name="filterChainDefinitions">        <value>            /index.jsp=anon            /unauth.jsp=anon            /user/login=anon            /static/**=anon            /robots.txt=anon            /**=authc        </value>    </property></bean>


自定义Loginrealm类,该类必须继承AuthorizingRealm类做爸爸,重写两个方法,一个是认证另一个授权

package com.yxb.user.controller;import com.yxb.user.domain.AdminUser;import com.yxb.user.service.UserService;import com.yxb.utils.log.UUIDUtil;import com.yxb.utils.shiro.TokenManager;import org.apache.shiro.authc.*;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import java.util.Set;/** * 定义权限管理器 */public class LoginRealm extends AuthorizingRealm {    @Autowired    private UserService userService;    // 定义logger    Logger logger = LoggerFactory.getLogger("auth");    @Override    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {        String uid = UUIDUtil.getOnlyOneCode();        Long userId = TokenManager.getUserId();        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();        logger.info("[用户授权](业务码:{}) : 用户 {} ,正在授权操作...", uid, TokenManager.getNickname());        //根据用户ID查询角色(role),放入到Authorization里。        Set<String> roles = userService.selectAdminRoles(userId);        info.setRoles(roles);        logger.info("[用户授权](业务码:{}) : 用户 {} ,授予:{} 角色成功!", uid, TokenManager.getNickname(), roles.toString());        //根据用户ID查询权限(permission),放入到Authorization里。        Set<String> permissions = userService.selectAdminPermissions(userId);        logger.info("[用户授权](业务码:{}) : 用户 {} ,授予:{} 权限成功!", uid, TokenManager.getNickname(), permissions.toString());        info.setStringPermissions(permissions);        return info;    }    @Override    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {        String uid = UUIDUtil.getOnlyOneCode();        // 1. 转化成用户名密码令牌        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;        // 2. 判断用户名密码的可用性        String userName = token.getUsername();        logger.info("[登录认证](业务码:{}) : 用户 {} ,正在登录验证...", uid, userName);        if (userName != null && !"".equals(userName)) {            // 3. 判断用户名密码的正确行            AdminUser adminUser = userService.loginForWeb(token.getUsername(), String.valueOf(token.getPassword()));            if (adminUser == null) {                logger.info("[登录认证](业务码:{}) : 用户 {} ,发生'帐号或密码不正确!'异常,登录失败", uid, userName);                throw new IncorrectCredentialsException("帐号或密码不正确!");            } else {                if (adminUser.getState() == 0) {                    logger.info("[登录认证](业务码:{}) : 用户 {} ,认证失败: 用户已经禁用", uid, userName);                    throw new DisabledAccountException("用户已被禁用!");                }                logger.info("[登录认证](业务码:{}) : 用户 {} ,认证成功", uid, userName);                return new SimpleAuthenticationInfo(adminUser, String.valueOf(token.getPassword()), getName());            }        } else {            logger.info("[登录认证](业务码:{}) : 用户 {} ,发生'用户名不可为空!'异常,登录失败", uid, userName);            throw new IncorrectCredentialsException("用户名不可为空!");        }    }}

登陆方法

/** * 用于用户登录 * * @param username * @param password * @param verifyCode * @return 错误信息 */@PostMapping("/login")public String login(HttpServletRequest request, String username, String password, String verifyCode, boolean rememberMe) {    String msg = "redirect:home/main";    try {        AdminUser user = new AdminUser();        user.setUsername(username);        user.setPassword(password);        TokenManager.login(user, rememberMe);        return msg;    } catch (IncorrectCredentialsException e) {        msg = "登录密码错误.";        return "redirect:/common/login?error=" + URLUtils.URLencoder(msg);    } catch (ExcessiveAttemptsException e) {        msg = "登录失败次数过多.";        return "redirect:/common/login?error=" + URLUtils.URLencoder(msg);    } catch (LockedAccountException e) {        msg = "帐号已被锁定.";        return "redirect:/common/login?error=" + URLUtils.URLencoder(msg);    } catch (DisabledAccountException e) {        msg = "帐号已被禁用.";        return "redirect:/common/login?error=" + URLUtils.URLencoder(msg);    } catch (ExpiredCredentialsException e) {        msg = "帐号已过期.";        return "redirect:/common/login?error=" + URLUtils.URLencoder(msg);    } catch (UnknownAccountException e) {        msg = "帐号不存在.";        return "redirect:/common/login?error=" + URLUtils.URLencoder(msg);    } catch (UnauthorizedException e) {        msg = "您没有得到相应的授权!";        return "redirect:/common/login?error=" + URLUtils.URLencoder(msg);    }}

shiro的TokenManager

package com.yxb.utils.shiro;import com.yxb.user.domain.AdminUser;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.session.Session;public class TokenManager {    /**     * 获取当前登录的用户User对象     * @return     */    public static AdminUser getToken() {        AdminUser token = (AdminUser) SecurityUtils.getSubject().getPrincipal();        return token;    }    /**     * 获取当前用户的Session     *     * @return     */    public static Session getSession() {        return SecurityUtils.getSubject().getSession();    }    /**     * 把值放入到当前登录用户的Session里     *     * @param key     * @param value     */    public static void setVal2Session(Object key, Object value) {        getSession().setAttribute(key, value);    }    /**     * 从当前登录用户的Session里取值     *     * @param key     * @return     */    public static Object getVal2Session(Object key) {        return getSession().getAttribute(key);    }    /**     * 获取验证码,获取一次后删除     *     * @return     */    public static String getYZM() {        String code = (String) getSession().getAttribute("CODE");        getSession().removeAttribute("CODE");        return code;    }    /**     * 判断是否登录     *     * @return     */    public static boolean isLogin() {        return null != SecurityUtils.getSubject().getPrincipal();    }    /**     * 登录     *     * @param user     * @param rememberMe     * @return     */    public static AdminUser login(AdminUser user, Boolean rememberMe) {        UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());        token.setRememberMe(rememberMe);        SecurityUtils.getSubject().login(token);        return getToken();    }    /**     * 退出登录     */    public static void logout() {        SecurityUtils.getSubject().logout();    }    /**     * 检查权限     * @param permissions     */    public static void hasPermissions(String ...permissions){        SecurityUtils.getSubject().checkPermissions(permissions);    }}

当用户登录成功之后,shiro安全框架就会将用户的信息存放在session中,你可以通过User user = (User) SecurityUtils.getSubject().getPrincipal();这句代码在任何地方任何时候都能获取当前登录成功的用户信息。

这也是TokenManager 中调用之处

/** * 登录 * * @param user * @param rememberMe * @return */public static AdminUser login(AdminUser user, Boolean rememberMe) {    UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());    token.setRememberMe(rememberMe);    SecurityUtils.getSubject().login(token);    return getToken();}
/** * 获取当前登录的用户User对象 * * @return */public static AdminUser getToken() {    AdminUser token = (AdminUser) SecurityUtils.getSubject().getPrincipal();    return token;}

阅读全文
0 0
原创粉丝点击