1,使用shiro来完成认证工作,默认情况下使用的是iniRealm。如果需要使用其他realm,那么需要进行相关的配置。
2,Ini配置文件讲解:
- [main] section是你配置应用程序的SecurityManager实例及任何它的依赖组件(realm)的地方
- [users] section允许你定义一组静态的用户账号。这在大部分拥有少数用户账号或用户账号不需要再运行时被动态的创建的环境下是很有用的。
-
[roles] section 允许你定义在[users]section中的角色与权限关联起来。另外,这在大部分拥有少数用户或用户账号不需要再运行时被动态的创建的环境下是很有用的。
3,使用jdbcRealm来完成身份认证。
通过观察JdbcRealm源码可知,要实现JdbcRealm:
a),需要为jdbc设置dataSource
b),在指定的dataSource所对应的数据库中应用户表users,该表中由 username,password,password_salt等字段
c),Shiro.ini配置文件:c3p0连接池
[main]
dataSource=com.mchange.v2.c3p0.ComboPooledDataSource
dataSource.driverClass=com.mysql.jdbc.Driver
dataSource.jdbcUrl=jdbc:mysql://IP地址:3306/shiro
dataSource.user=数据库连接用户名
dataSource.password=数据库连接密码
jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.dataSource=$dataSource
securityManager.realm=$jdbcRealm
代码:
public static void main(String[] args) {
// 1,创建SecurityManager工厂来读取相应的配置文件
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
// 2,通过SecurityManager工厂获取SecurityManager实例
SecurityManager securityManager = factory.getInstance();
// 3,将SecurityManager对象 设置到运行环境中
SecurityUtils.setSecurityManager(securityManager);
// 4,SecurityUtils获取Subject主体
Subject subject = SecurityUtils.getSubject();
// 5,假如登录的用户是name和password,这个地方的name和password表示用户登录时输入的信息
UsernamePasswordToken token = new UsernamePasswordToken("sihaihou", "123456");
try {
// 6,进行用户身份验证
subject.login(token);
// 7,通过Subject判断用户是否通过验证
if (subject.isAuthenticated())
System.out.println("用户登录成功!");
} catch (UnknownAccountException e) {
System.out.println("用户或密码错误");
}catch (IncorrectCredentialsException e) {
System.out.println("用户或密码错误");
}
}
4,Authentication Strategy:认证策略,在shiro中有三种验证策略:
- AtLeastOneSuccessfulStrategy:如果一个或多个验证成功,则整体的尝试被认为是成功的。如果没有一个验证成功,则整体尝试失败。
- FirstSuccessfulStrategy:只要有一个成功验证的realm返回的信息将被使用,所有进一步的realm将被忽略。如果没有一个验证成功,则整体尝试失败。
3. AllSuccessfulStrategy:为了整体的尝试成功,所有配置的realm必须验证成功。如果有一个验证失败,则整体尝试失败
5,ini配置认证策略
authenticationStrategy=org.apache.shiro.authc.pam.AllSuccessfulStrategy
securityManager.authenticator.authenticationStrategy=$authenticationStrategy
6,自定义认证Realm
jdbcRealm已经实现了从数据库中获取用户的验证信息,但是jdbcRealm灵活性太差,如果要实现自己的一些特殊应用时将不能支持,这个时候可以通过自定义realm来实现身份的认证功能。
Realm是一个接口,在接口中定义了根据token获取认证信息的方法,shiro内容实现了一系列的realm.这些不同的Realm实现类提供了不同的功能,AuthenticatingRealm实现了获取身份信息的功能,AuthorizingRealm实现了获取权限信息的功能。通常自定义Realm需要继承AuthorizingRealm,既提供了身份认证的自定义方法也可以实现授权的自定义方法。
UserRealm.java
/**
* 自定义realm
* @author reyco
*/
public class UserRealm extends AuthorizingRealm{
@Override
public String getName() {
return super.getName();
}
/**
* 完成身份认证(从数据库取数据),并且返回认证信息
* 如果身份认证失败返回null
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//获取用户输入的用户名
Object username = token.getPrincipal();
//获取密码/作jdbc获取数据
String password = "123456";
//将从数据库中查询的信息封装到SimpleAuthenticationInfo中
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, password, getName());
//返回认证信息
return simpleAuthenticationInfo;
}
/**
* 授权的信息
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection token) {
return null;
}
}
shiro.ini配置:
[main]
userRealm=com.shiro.reyco.core.realm.UserRealm ## 自定义的Realm的全类名
#securityManager.realms=$userRealm