简介:
百度百科:Shiro
Shiro 官方主页:http://shiro.apache.org/download.html
身份认证
1) Subject 认证主体
Subject 认证主体包含两个信息:
Principals:身份,可以是用户名,邮件,手机号码等等,用来标识一个登录主体身份;
Credentials:凭证,常见有密码,数字证书等等;
2)身份认证流程
/**
*
- 身份认证
- Subject 认证主体
- Subject 认证主体包含两个信息:
- Principals:身份,可以是用户名,邮件,手机号码等等,用来标识一个登录主体身份;
- Credentials:凭证,常见有密码,数字证书等等;
- @author Administrator
*/
public class JdbcRealmTest {
public static void main(String[] args) {
/**
* 读取配置文件,初始化SecurityManager工厂
*/
Factory<SecurityManager> factory=
new IniSecurityManagerFactory("classpath:jdbc_realm.ini");
/**
* 获取securityManager实例
*/
SecurityManager securityManager=factory.getInstance();
/**
* 把securityManager实例绑定到SecurityUtils
*/
SecurityUtils.setSecurityManager(securityManager);
/**
* 得到当前执行的用户
*/
Subject currentUser=SecurityUtils.getSubject();
/**
* 创建token令牌,用户名/密码
*/
UsernamePasswordToken token=new UsernamePasswordToken("java1234","123456");
try{
/**
* 身份认证
*/
currentUser.login(token);
System.out.println("身份认证成功");
}catch(AuthenticationException e){
e.printStackTrace();
System.out.println("身份认证失败");
}
//退出
currentUser.logout();
}
}
3)Realm & JDBC Realm
Realm:域,Shiro从Realm中获取验证数据;
Realm 有很多种类,列如常见的jdbc realm, jndi realm, text realm。
权限认证(授权)
1)权限认证核心要素
权限认证,就是访问控制,即在应用中控制谁能访问哪些资源。
在权限认证中,最核心的三要素是:权限、角色和用户;
权限,即操作资源的权利,比如访问某个页面,以及对某个模块的数据的添加,修改,删除,查看的权利;
角色,即权限的集合,一个角色中可以包含多种权限;
用户,在Shiro中,代表访问系统的用户,即Subject;
2)授权
1.编程式授权
1.1 基于角色的访问控制
1.2 基于权限的访问控制
2.注解式授权
@RequiresAuthentication 要求当前的Subject以及在当前的session中被验证通过才能被访问或调用。
@RequiresGuest 要求当前的Subject是一个"guest",也就是必须在之前的session中没有被验证或者被记住才能被访问或者被调用
@RequiresPermissions(“account:create”) 要求当前的Subject被允许一个或多个权限,以便执行注解的方法。
@RequiresRoles(“administrator”)要求当前的Subject拥有指定的角色,若没有,则该方法将不会被执行,而且AuthorizationException 异常将会抛出。
3.JSP标签授权
Guest标签:用户没有身份认证时显示相应的信息,即游客访问信息
User标签:用户已经身份认证/记住我登录后相应的信息
Authenticated标签:用户已经身份认证通过,即Subject.login 登录成功,不是记住我登录的。
notAuthenticated标签:用户没有身份认证通过,既没有调用Subject.login登录,包括记住我自动登录的也属于未进行身份验证。
principal标签:显示用户身份信息,默认调用Subject.getPrincipal()获取,即Primary Principal。
hasRole标签:如果当前Subject有角色将显示body体内容
lacksRole标签:如果当前Subject没有角色将显示body体内容。
hasAnyRoles标签:如果当前Subject有任意一个角色(或的关系)将显示body体内容。
hasPermission标签:如果当前Subject有权限将显示body体内容。
lacksPermission标签:如果当前Subject没有权限将显示body体内容。
3)授权流程
集成WEB
1)配置
2)Shiro集成Web具体使用
Url匹配方式
?匹配一个字符/admin? 可以匹配/admin1 /admin2 但是不能匹配/admin1 2/admin
- 匹配零个或者一个或者多个字符/admin* 可以匹配/admin /admin1/admin12 但是不能匹配/admina/abc
** 匹配零个或者多个路径/admin/** 可以匹配/admin/admin/a /admin/a/b
登录授权 /身份认证
public class MyRealm extends AuthorizingRealm{
private UserDao userDao=new UserDao();
private DbUtil dbUtil=new DbUtil();
/**
* 为当前登录的用户授予角色和权限
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
/**
* 登录成功后
* 通过userName获取权限 角色
*/
String userName=(String) principals.getPrimaryPrincipal();
SimpleAuthorizationInfo authorizationInfo=new SimpleAuthorizationInfo();
Connection con=null;
try{
con=dbUtil.getCon();
authorizationInfo.setRoles(userDao.getRoles(con,userName));
authorizationInfo.setStringPermissions(userDao.getPermissions(con, userName));
}catch(Exception e){
e.printStackTrace();
}finally{
try{
dbUtil.closeCon(con);
}catch(Exception e){
e.printStackTrace();
}
}
return authorizationInfo; //返会的是一些权限封装的信息
}
/**
* 验证当前登录的用户
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String userName=(String)token.getPrincipal(); //获取用户名 密码
Connection con=null;
try{
con=dbUtil.getCon();
User user=userDao.getByUserName(con, userName);
if(user!=null){
AuthenticationInfo authcInfo=new SimpleAuthenticationInfo(user.getUserName(),user.getPassword(),"xx");
return authcInfo;
}else{
return null;
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{
dbUtil.closeCon(con);
}catch(Exception e){
e.printStackTrace();
}
}
return null; //即用户名/密码不对 返回nulls
}
}
加密
/**
- 加密解密
- @author Administrator
/
public class CryptographyUtil {
/*
-
base64加密 可逆
-
@param str
-
@return
/
public static String encBase64(String str){
return Base64.encodeToString(str.getBytes());
}
/*- base64解密
- @param str
- @return
*/
public static String decBase64(String str){
return Base64.decodeToString(str);
}
/**
- Md5加密
- @param str
- @param salt
- @return
*/
public static String md5(String str,String salt){
return new Md5Hash(str,salt).toString();
}
/**
*测试加密解密效果- @param args
*/
public static void main(String[] args) {
String password=“123456”;
System.out.println(“Base64解密:”+CryptographyUtil.encBase64(password));
System.out.println(“Base64解密:”+CryptographyUtil.decBase64(CryptographyUtil.encBase64(password)));
System.out.println(“Md5加密:”+CryptographyUtil.md5(password, “java1234”));
}
}