Shiro安全框架

目录

什么是Shiro

Shiro核心组件

Shiro的运行机制

案例

导入依赖

自定义Realm

配置类

控制层

什么是Shiro

Shiro是一款Java安全框架,他不依赖任何容器,主要功能是对访问的用户进行身份认证、授权、会话管理、加密等操作。

Shiro核心组件

授权一般分用户、角色、权限

权限赋给角色,角色赋给用户

  1. UsernamePasswordToken,这是Shiro用来封装用户的登录信息,使用用户的登陆的信息来创建令牌Token。
  2. SecurityManager,Shiro的核心部分,负责安全认证和授权。
  3. Subject,Shiro的一个抽象的概念,包含用户信息。
  4. Realm,开发者根据项目需求自定义的模块,验证,授权的逻辑全部写在Realm中。
  5. Authenticationinfo,用户的角色信息集合,认证时使用。
  6. Authorzationinfo,角色的权限信息集合,授权时使用。
  7. DefaultWebSecurityManager,安全管理器,开发者定义的Realm要注入到安全管理器中才能使用。
  8. ShiroFilterFactoryBean,过滤器工厂,Shiro的基本运行机制时开发者定制规则,Shiro去执行,具体的执行操作是过滤器工厂创建的Filter对象完成的。

Shiro的运行机制

  1. 首先用户先登录拿到Token(Shiro通过UsernamePasswordToken创建Token)
  2. Token需要拿到Subject(包含用户信息)验证信息
  3. SecurityManager通过Authenticationinfo和Authorzationinfo读取自定义的Realm的具体操作。

案例

导入依赖

<dependencies>
    <!--Shiro核心包-->
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-core</artifactId>
        <version>1.10.0</version>
    </dependency>
    <!--日志相关包-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>2.0.0-alpha2</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>2.0.0-alpha2</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
</dependencies>

自定义Realm

public class AccoutRealm extends AuthorizingRealm {

    @Autowired
    private AccountService accountService;

    /**
     * 授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取当前登录的用户信息
        Subject subject = SecurityUtils.getSubject();
        Account account = (Account) subject.getPrincipal();

        //设置角色,使用set是因为set不可重复
        Set<String> roles = new HashSet<>();
        roles.add(account.getRole());
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roles);

        //设置权限
        info.addStringPermission(account.getPerms());
        return info;
    }


    /**
     * 认证
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        Account account = accountService.findByUsername(token.getUsername());
        if(account != null){
            return new SimpleAuthenticationInfo(account,account.getPassword(),getName());
        }
        return null;
    }
}

配置类

需要将Realm注入进安全管理器,然后将安全管理器注入给工厂类才能使用。

anon:无需认证。

authc:必须认证。

authcBasic:需要通过 HTTPBasic 认证。

user:不一定通过认证,只要曾经被 Shiro 记录即可,比如:记住我。

@Configuration
public class ShiroConfig {


    @Bean
    public AccoutRealm accoutRealm(){
        return new AccoutRealm();
    }

    @Bean
    public DefaultWebSecurityManager securityManager(@Qualifier("accoutRealm") AccoutRealm accoutRealm){
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        manager.setRealm(accoutRealm);
        return manager;
    }

       @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager);
        //权限设置
        Map<String,String> map = new Hashtable<>();
        map.put("/main","authc");
        map.put("/manage","perms[manage]");
        map.put("/administrator","roles[administrator]");
        factoryBean.setFilterChainDefinitionMap(map);
        //设置登录页面
        factoryBean.setLoginUrl("/login");
        //设置未授权页面
        factoryBean.setUnauthorizedUrl("/unauth");
        return factoryBean;
    }

 
}

控制层

  @PostMapping("/login")
    public String login(String username, String password, Model model){
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username,password);
        try {
            //subject.login自动调用Realm中的认证方法
            subject.login(token);
            Account account = (Account) subject.getPrincipal();
            subject.getSession().setAttribute("account",account);
            return "index";
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            model.addAttribute("msg","用户名错误!");
            return "login";
        } catch (IncorrectCredentialsException e){
            model.addAttribute("msg","密码错误!");
            e.printStackTrace();
            return "login";
        }
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值