安全框架 用户认证

这里写图片描述
一、用户登录的Controller控制层代码

@Controller
@RequestMapping("/")
public class LoginController {

    @ResponseBody
    @RequestMapping("doLogin")
    public JsonResult doLogin(String username,
            String password){
        //对用户身份进行认证
        //获取主体对象
        Subject subject = SecurityUtils.getSubject();
        //提交用户信息
        UsernamePasswordToken token = new UsernamePasswordToken(username,password);
        subject.login(token);
        return new JsonResult("login ok");
    }   
}

二、获取用户信息(交给安全框架),并进行认证授权
写Realm类

/**
 *Realm为Shiro框架中的核心业务组件之一
 *通过此对象可以完成数据业务的获取以及封装
 */
@Service
public class ShiroUserRealm extends AuthorizingRealm{
    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private SysRoleMenuDao sysRoleMenuDao;
    @Autowired  
    private SysUserRoleDao sysUserRoleDao;
    @Autowired
    private SysMenuDao sysMenuDao;


    /**
     * 设置凭证(Credentials)匹配器
     */
    @Override
    public void setCredentialsMatcher(
            CredentialsMatcher credentialsMatcher) {
        HashedCredentialsMatcher cMatcher=new HashedCredentialsMatcher();
        cMatcher.setHashAlgorithmName("MD5");
        //设置加密的次数(这个次数应该与保存密码时那个加密次数一致)
        //cMatcher.setHashIterations(5);
        super.setCredentialsMatcher(cMatcher);
    }

    /**在此方法中完成认证信息的获取以及封装*/
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken token) throws AuthenticationException {
        //1.获取用户身份对象(例如用户名)
        String username=(String)token.getPrincipal();
        System.out.println("username="+username);
        //2.基于用户名从数据库查询记录
        SysUser user=sysUserDao.findUserByUserName(username);
        //3.对查询结果进行验证,用户不存在则抛出异常
        if(user==null)
            throw new AuthenticationException("用户不存在");
        if(user.getValid()==0)
            throw new AuthenticationException("用户已被禁用");
        //4.对数据库查询出的相关信息进行封装
        ByteSource credentialsSalt=ByteSource.Util.bytes(user.getSalt());
        SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(
                user,//principal (身份对象)
                user.getPassword(), //hashedCredentials(已加密的密码)
                credentialsSalt,//credentialsSalt (盐)
                this.getName());
        //5.返回封装结果(传递给认证管理器)
        return info;
    }

    /**在此方法中完成授权信息的获取以及封装*/
/**
 *Realm为Shiro框架中的核心业务组件之一
 *通过此对象可以完成数据业务的获取以及封装
 */
@Service
public class ShiroUserRealm extends AuthorizingRealm{
    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private SysRoleMenuDao sysRoleMenuDao;
    @Autowired  
    private SysUserRoleDao sysUserRoleDao;
    @Autowired
    private SysMenuDao sysMenuDao;


    /**
     * 设置凭证(Credentials)匹配器
     */
    @Override
    public void setCredentialsMatcher(
            CredentialsMatcher credentialsMatcher) {
        HashedCredentialsMatcher cMatcher=new HashedCredentialsMatcher();
        cMatcher.setHashAlgorithmName("MD5");
        //设置加密的次数(这个次数应该与保存密码时那个加密次数一致)
        //cMatcher.setHashIterations(5);
        super.setCredentialsMatcher(cMatcher);
    }

    /**在此方法中完成认证信息的获取以及封装*/
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken token) throws AuthenticationException {
        //1.获取用户身份对象(例如用户名)
        String username=(String)token.getPrincipal();
        System.out.println("username="+username);
        //2.基于用户名从数据库查询记录
        SysUser user=sysUserDao.findUserByUserName(username);
        //3.对查询结果进行验证,用户不存在则抛出异常
        if(user==null)
            throw new AuthenticationException("用户不存在");
        if(user.getValid()==0)
            throw new AuthenticationException("用户已被禁用");
        //4.对数据库查询出的相关信息进行封装
        ByteSource credentialsSalt=ByteSource.Util.bytes(user.getSalt());
        SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(
                user,//principal (身份对象)
                user.getPassword(), //hashedCredentials(已加密的密码)
                credentialsSalt,//credentialsSalt (盐)
                this.getName());
        //5.返回封装结果(传递给认证管理器)
        return info;
    }

    /**在此方法中完成授权信息的获取以及封装*/
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(
            PrincipalCollection principals) {
        System.out.println("doGetAuthorizationInfo");
        //1.获取登录用户具有的权限信息
        //1.1获取用户身份对象
        SysUser user=(SysUser)principals.getPrimaryPrincipal();
        //1.2基于用户id获取角色id(可能多个):查中间表sys_user_roles;
        List<Integer> roleIds=sysUserRoleDao.findRoleIdsByUserId(user.getId());
        //1.3基于角色id获取菜单id(可能多个):查中间表sys_role_menus
        List<Integer> menuIds=sysRoleMenuDao.findMenuIdsByRoleId(
                        roleIds.toArray(new Integer[]{}));
        //1.4基于菜单id获取权限标识(sys:user:valid):查询菜单表sys_menus;
        List<String> permissions=sysMenuDao.findPermissions(
                        menuIds.toArray(new Integer[]{}));
        //2.对权限信息封装
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
        //3.返回封装结果(授权管理器);
        Set<String> set=new HashSet<>();
        for(String per:permissions){
            if(!StringUtils.isEmpty(per)){
                set.add(per);
            }
        }
        info.setStringPermissions(set);
        return info;
    }
}

三、将身份交给realm

@Configuration
public class AppShiroConfig {

    /**
     * 配置shiro的SecurityManager对象
     */
    @Bean("securityManager")
    public SecurityManager newSecurityManager(
            AuthorizingRealm realm){
        DefaultWebSecurityManager sManager = new DefaultWebSecurityManager();
        //通过reaml访问数据库
        sManager.setRealm(realm);
        return sManager; 
    }

SysUserRoleMapper中元素定义

    <select id="findRoleIdsByUserId"
            resultType="int">
           select role_id
           from sys_user_roles
           where user_id=#{userId}        
</select>

SysRoleMenuMapper中元素定义

   <select id="findMenuIdsByRoleId"
         resultType="int">
         select menu_id
         from sys_role_menus
         where role_id in 
         <foreach collection="roleIds"
                  open="("
                  close=")"
                  separator=","
                  item="item">
               #{item}
         </foreach>
     </select>

SysMenuMapper中元素定义

   <select id="findPermissions"
           resultType="string">
       select permission <!-- sys:user:update -->
       from sys_menus
       where id in 
       <foreach collection="menuIds"
                open="("
                close=")"
                separator=","
                item="item">
            #{item}
       </foreach>
   </select>

授权检测实现
在需要进行授权检测的方法上添加执行此方法需要的权限标识
例如

@RequestPermissions(“sys:user:valid”)

猜你喜欢

转载自blog.csdn.net/qq1083273166/article/details/82459791