shiro认证流程

shiro-web认证流程

一、认证流程

  1. 访问Controller接口,获取Subject对象,实现UsernamePasswordToken,调用subject对象login方法,进入AuthenticationRealm对象中的getAuthenticationInfo方法中。
  2. 先判断缓存中是否存在认证信息,若没有跳转到自定义Realm【注册到SubjectManager中[并且在Realm中配置加密策略]】的doGetAuthenticationInfo中,通过token获取用户名调用数据库获取用户信息,封装为SimpleAuthenticationInfo对象返回即可。

二、注册自定义Realm

作用 :实现认证和授权

继承AuthorizingRealm类重载 protected AuthenticationInfo doGtAuthenticationInfo(AuthenticationToken token)

三、Code

1、配置自定义Realm

public class MyShiroRealm extends AuthorizingRealm {

    @Resource
    private AdminUserService adminUserService;

    @Resource
    private PermissionService permissionService;

    /**
     * 授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        Integer id = (Integer) principalCollection.getPrimaryPrincipal();
        List<Permission> permissionList = permissionService.loadUserPermission(id);
        // 权限信息对象info,用来存放查出的用户的所有的角色(role)及权限(permission)
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        permissionList.forEach(p->info.addStringPermission(p.getPerurl()));
        return info;
    }

    /**
     * 认证
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //获取用户的输入的账号.
        String username = (String)token.getPrincipal();
        AdminUser user = adminUserService.findByUserName(username);
        if(user==null) throw new UnknownAccountException();
        if (0==user.getEnable()) {
            throw new LockedAccountException(); // 帐号锁定
        }
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                user.getId(), //用户
                user.getPassword(), //密码
                ByteSource.Util.bytes(username),
                getName() //realm name
        );
        // 把用户信息放在session里
        Session session = SecurityUtils.getSubject().getSession();
        session.setAttribute("AdminSession", user);
        session.setAttribute("AdminSessionId", user.getId());
        return authenticationInfo;
    }
}

2、配置Realm到SecurityManager

@Configuration
public class ShiroConfig {
    @Autowired
    private PermissionService permissionService;

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    @Value("${spring.redis.timeout}")
    private int timeout;

    @Value("${spring.redis.password}")
    private String password;

     /**
     * 凭证匹配器
     *
     * @return
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();

        hashedCredentialsMatcher.setHashAlgorithmName("md5");
        hashedCredentialsMatcher.setHashIterations(2);//散列的次数,相当于 md5(md5(""));
        return hashedCredentialsMatcher;
    }

    //配置自定义Realm
    @Bean
    public Realm getMyShiroRealm() {
        MyShiroRealm mShiroRealm = new MyShiroRealm();
    	//配置加密凭证
        mShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return mShiroRealm;
    }

    //配置SecurityManager
    @Bean
    public SecurityManager securityManager() {
        //类似于DispatcherServlet
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //设置realm.【类似于DataSource】
        securityManager.setRealm(getMyShiroRealm());
        return securityManager;
    }
    
    /**
     * 处理拦截资源文件问题。
     *
     * @param securityManager
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        // 设置 SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        // 如果不设置默认会自动寻找Web工程根目录下的"/login.html"页面
        shiroFilterFactoryBean.setLoginUrl("/login");
        // 登录成功后要跳转的链接
        shiroFilterFactoryBean.setSuccessUrl("/initPage");
        //未授权界面
        shiroFilterFactoryBean.setUnauthorizedUrl("/forbidden");
        //拦截器.
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        filterChainDefinitionMap.put("/favicon.png", "anon");//解决弹出favicon.ico下载
        filterChainDefinitionMap.put("/logout", "logout");
        filterChainDefinitionMap.put("/css/**", "anon");
        filterChainDefinitionMap.put("/js/**", "anon");
        filterChainDefinitionMap.put("/img/**", "anon");
        filterChainDefinitionMap.put("/font-awesome/**", "anon");
        filterChainDefinitionMap.put("/", "anon");

        //自定义加载权限资源关系
        List<Permission> list = permissionService.findAll();
        for (Permission p : list) {
            if (!p.getPerurl().isEmpty()) {
                String permission = "perms[" + p.getPerurl() + "]";
                filterChainDefinitionMap.put(p.getPerurl(), permission);
            }
        }

        //过滤链定义,从上向下顺序执行,一般将 /**放在最为下边
        filterChainDefinitionMap.put("/**", "authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }


}

四、shiro组织架构【图片】

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值