入门代码
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