Shiro框架入门

入门代码
pom 文件

<dependency>
  		<groupId>org.apache.shiro</groupId>
  		<artifactId>shiro-all</artifactId>
  		<version>1.4.0</version>
  		<type>pom</type>
  	</dependency>
  	  <dependency>
        	<groupId>org.slf4j</groupId>
        	<artifactId>slf4j-api</artifactId>
        	<version>1.7.12</version>
        </dependency>
        <dependency>
        	<groupId>org.slf4j</groupId>
        	<artifactId>slf4j-log4j12</artifactId>
        	<version>1.7.12</version>
        </dependency>
	<dependency>
        	<groupId>log4j</groupId>
        	<artifactId>log4j</artifactId>
        	<version>1.2.16</version>
      </dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.3.13.RELEASE</version>
</dependency>

shiro.ini

# -----------------------------------------------------------------------------
# Users and their (optional) assigned roles (用户及角色)
# username = password, role1, role2, ..., roleN
# -----------------------------------------------------------------------------
[users]
root = 1234, admin
guest = 1234, guest

# -----------------------------------------------------------------------------
# Roles with assigned permissions (角色及权限)
# roleName = perm1, perm2, ..., permN
# -----------------------------------------------------------------------------
[roles]
admin = *
guest = user:*

java代码

  //默认使用的底层源是IniRealm
public static void main(String[] args){
        //1.创建安全管理器工厂(加载shiro.ini,读取其中用户名和密码,放入内存中)
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        //2.获取安全管理器
        SecurityManager manager = factory.getInstance();
        //3.注册安全管理器
        SecurityUtils.setSecurityManager(manager);
        //4.获取认证主体(可以理解为当前要登录的用户,需携带用户名和密码-即令牌,交由shiro去认证)
        Subject subject = SecurityUtils.getSubject();
        //5.输入用户名和密码,生成token令牌,去认证
        //如果用户名错误,抛出UnknownAccountException,如果密码错误,抛出IncorrectCredentialsException
        UsernamePasswordToken token = new UsernamePasswordToken("guest", "1234");
        //6.使用令牌认证
        try{
            subject.login(token);
            System.out.println("认证成功");
            //认证成功,可以获取用户相关信息
            System.out.println("登录用户名===>"+subject.getPrincipal());
            //当前用户具有的角色
            System.out.println("当前用户是否具有admin角色====>"+subject.hasRole("admin"));
            System.out.println("当前用户是否具有guest角色====>"+subject.hasRole("guest"));
            //当前用户是否具有相应权限
            System.out.println("当前用户是否具有*权限====>"+subject.isPermitted("*"));
            System.out.println("当前用户是否具有user:*权限====>"+subject.isPermitted("user:*"));
            //7.退出登录
            subject.logout();
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("认证失败");
        }


    }
```//手动创建IniRealm,加载config文件
public static void main(String[] args) {
        //1.创建安全管理器工厂
        Realm realm = new IniRealm("classpath:shiro.ini");
        //2.获取安全管理器
        SecurityManager manager = new DefaultSecurityManager(realm);
        //3.注册安全管理器
        SecurityUtils.setSecurityManager(manager);
        //4.获取认证主体(来自shiro.ini)............其他与上相同.....
      

    }

入门示例二
通过加载shiro.ini,连接数据库

用户和角色一对多关系

角色和权限一对多关系
#所执行的数据库语句
select password from users where username = ?
select role_name from user_roles where username = ?
select permission from roles_permissions where role_name = ?
#对象名 = 全限定类名 相对于调用 public 无参构造器创建对象
#对象名. 属性名 = 值 相当于调用 setter 方法设置常量值
#对象名. 属性名 =$ 对象引用 相当于调用 setter 方法设置对象引用
[main]
dataSource=com.alibaba.druid.pool.DruidDataSource
dataSource.driverClassName=com.mysql.jdbc.Driver
dataSource.url=jdbc:mysql:///shiro
dataSource.username=root
dataSource.password=tiger

jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.dataSource=$dataSource
securityManager.realms=$jdbcRealm



上面config文件配置,相当于使用如下代码等同

通过手动创建JdbcRealm,连接数据库

public static void main(String[] args) {
        //1.创建安全管理器工厂,使用JdbcRealm
        JdbcRealm realm = new JdbcRealm();
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql:///shiro");
        dataSource.setUsername("root");
        dataSource.setPassword("tiger");
        realm.setDataSource(dataSource);
        //2.获取安全管理器
        SecurityManager manager = new DefaultSecurityManager(realm);
        //3.注册安全管理器
        SecurityUtils.setSecurityManager(manager);
        //4.获取认证主体(来自shiro.ini)
        Subject subject = SecurityUtils.getSubject();
    	//....................

    }
    入门示例三
    也可以自定义Realm,使用自己查询方式
    /**
 * 自己提供认证和授权方式,注意:继承JdbcRealm
 */
public class MyJdbcRealm extends JdbcRealm {

    /**
     * 认证
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken upToken = (UsernamePasswordToken)token;
        //通过token中用户名,去数据库中查找用户,查出密码
        String username = upToken.getUsername();
        if (username == null) {
            throw new AccountException("用户名不能为空");
        } else {
            Connection conn = null;
            SimpleAuthenticationInfo info = null;
            try{
                conn = this.dataSource.getConnection();
                PreparedStatement preparedStatement = conn.prepareStatement("select password from users where username=?");
                preparedStatement.setString(1, username);
                ResultSet resultSet = preparedStatement.executeQuery();
                if(resultSet.next()){
                    String password = resultSet.getString(1);
                    if(password==null){
                        throw new UnknownAccountException("数据库中没有该用户===> [" + username + "]");
                    }
                    //把用户名和密码提交给shiro,shiro自动会对token进行认证
                    info = new SimpleAuthenticationInfo(username, password.toCharArray(), this.getName());
                    return info;
                }

            }catch (Exception e){
                e.printStackTrace();
            }finally {
                JdbcUtils.closeConnection(conn);
            }
        }
        return null;
    }

    /**
     * 授权
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        if (principals == null) {
            throw new AuthorizationException("用户授权失败");
        } else {
            String username = (String)this.getAvailablePrincipal(principals);
            Connection conn = null;
            Set<String> roleNames = new HashSet<>();
            Set permissions = new HashSet();

            try {
                conn = this.dataSource.getConnection();
                //通过用户名,查询出角色
                PreparedStatement preparedStatement = conn.
                        prepareStatement("SELECT rolename FROM role WHERE uid =(SELECT id FROM users WHERE username=?)");
                preparedStatement.setString(1, username);
                ResultSet resultSet = preparedStatement.executeQuery();
                while(resultSet.next()){
                    String rolename = resultSet.getString(1);
                    roleNames.add(rolename);
                }
           
                
 				//通过角色关联出权限
                if (!roleNames.isEmpty()) {
                   
                    preparedStatement = conn.
                            prepareStatement("SELECT func FROM permission WHERE rid IN" +
                                    " (SELECT id FROM role WHERE uid =(SELECT id FROM users WHERE username=?))");
                    preparedStatement.setString(1, username);
                    resultSet = preparedStatement.executeQuery();
                    while(resultSet.next()){
                        String permission = resultSet.getString(1);
                        permissions.add(permission);
                    }
                }
            } catch (SQLException var11) {
                var11.printStackTrace();
                throw new AuthorizationException("用户授权失败", var11);
            } finally {
                JdbcUtils.closeConnection(conn);
            }
            //把角色和权限给shiro,shiro会自动授权
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames);
            info.setStringPermissions(permissions);
            return info;
        }
    }
}
[main]

dataSource=com.alibaba.druid.pool.DruidDataSource
dataSource.driverClassName=com.mysql.jdbc.Driver
dataSource.url=jdbc:mysql:///shiro
dataSource.username=root
dataSource.password=tiger
#自定义Realm
jdbcRealm=com.sy.shiro.realm.MyJdbcRealm
jdbcRealm.dataSource=$dataSource

securityManager.realms=$jdbcRealm
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

头发乱了_257

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值