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

项目使用的是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
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值