Shiro 基本学习

本文介绍了Apache Shiro框架的三个核心概念:Subject、SecurityManager和Realm,并展示了如何在Spring环境中配置Shiro,包括自定义Realm实现认证和授权,以及设置过滤器链。在Controller层,提供了一个简单的登录示例。文中提到的权限和角色信息目前是硬编码的,实际应用中应从数据库中获取。
摘要由CSDN通过智能技术生成

 

 

 一: 三个主要的概念

1.subject:当前用户(可以是使用者也可以是第三方服务,主要指一个正在与当前软件交互的东西),所有的Subject都需要SecurityManager

2.SecurityManager :安全管理员,Shiro架构的核心

3.Realms:用于进行权限信息的验证,可以由我们自己实现。在配置 Shiro 的时候,我们必须指定至少一个Realm 来实现认证(authentication)和/或授权(authorization)。

二:基本使用

1.导入依赖:


        <!-- thymeleaf 与 shiro  整合-->
        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.0.0</version>
        </dependency>
        <!--整合shiro-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.1</version>
        </dependency>

2.配置类:

1)自定义一个Realm

public class UserRealm extends AuthorizingRealm {

    @Autowired
    UsersService usersService;

    /**
     * 授权
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 进入该方法说明已经通过认证了

        // principalCollection 中可以获得认证中传入的三个参数
        // 该数据就是认证时传入的用户信息
        Users users = (Users) principalCollection.getPrimaryPrincipal();
        // 也可以从Subject中获得当前用户的信息
        // Subject subject = SecurityUtils.getSubject();
        // Users user = (Users) subject.getPrincipal();

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addStringPermission("user:add"); // 给当前用户授权,可从数据库中获取进行授权,此处为手动授权

        return info;
    }

    /**
     * 认证
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 可以获得表单中输入的用户名和密码
        UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;
        // 根据输入的用户名从数据库中查找该用户
        Users users = usersService.queryUsersByUserName(userToken.getUsername());
        if (users.getUsername() == null || !userToken.getUsername().equals(users.getUsername())) {
            return null;// 自动抛出异常
        }
        // 密码认证不需要我们实现
        return new SimpleAuthenticationInfo(users, users.getPassword(), users.getUsername());
//       return new SimpleAuthenticationInfo("", users.getPassword(), "");
    }
}

 2)ShiroConfig 类

@Configuration
public class ShiroConfig {

    /**
     * 3 ShiroFilterFactoryBean
     *
     * @param defaultWebSecurityManager
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        // 设置安全关联器
        bean.setSecurityManager(defaultWebSecurityManager);
        /**
         * anon:无需认证就可以访问
         * authc:必须认证了才能访问
         * user:必须拥有 记住我 功能才能访问
         * perms:拥有对某个资源的权限才能访问
         * role:拥有某个介绍权限才能访问
         */
        // 添加shiro 的内置过滤器
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        // 授权
        filterChainDefinitionMap.put("/add", "perms[user:add]");
        filterChainDefinitionMap.put("/update", "authc");// 必须认证才能登录
        // 配置退出
        filterChainDefinitionMap.put("/logout", "logout");
        // 设置登录请求
        bean.setLoginUrl("/toLogin");
        // 设置未授权
        bean.setUnauthorizedUrl("/noauth");
        bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return bean;
    }

    /**
     * 2 DefaultWebSecurityManager
     *
     * @param userRealm
     * @return DefaultWebSecurityManager
     */
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 关联userRealm
        securityManager.setRealm(userRealm);
        return securityManager;
    }

    /**
     * 1、创建Realm对象
     *
     * @return Realm 一个实例对象
     */
    @Bean
    public UserRealm userRealm() {
        return new UserRealm();
    }

    /**
     * 创建ShiroDialect:用于整合shiro 和thymeleaf
     *
     * @return
     */
    @Bean
    public ShiroDialect getShiroDialect() {
        return new ShiroDialect();
    }
}

3 control层

  @RequestMapping("/login")
    public String login(String username, String password, Model model) {
        // 获取当前用户
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        try {
            subject.login(token);// 执行登录的方法,没有异常就可以成功
            return "index";
        } catch (UnknownAccountException e) {
            model.addAttribute("msg", "用户名错误");
            return "login";
        } catch (IncorrectCredentialsException e) {
            model.addAttribute("msg", "密码错误");
            return "login";
        }
    }

上述代码中用户的角色和权限信息没有从数据库中获取,都为自定义,可以修改这部分代码,将其改为从数据库中的获取。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值