shiro
1、shiro简介
Apache Shiro是一个强大且易用的Java安全框架,有身份验证、授权、密码学和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。
shiro四大基石:
1、Authentication(身份认证/登录)
2、Authorization(授权)
3、Session Management(会话管理)
4、Cryptography(密码学)
2、shiro架构
Subject: 表示当前用户,不一定是人,也有可能是网络爬虫、机器人等
SecurityManager: 安全管理器,shiro的核心
Realm: 获取安全数据(用户,角色,权限)
3、shiro入门
1、导包
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lxn</groupId>
<artifactId>shiro</artifactId>
<version>1.0-SNAPSHOT</version>
<!--使用shiro需要先导包-->
<dependencies>
<!--shiro的核心包-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.0</version>
</dependency>
<!--日志包-->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!--测试包-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
</dependencies>
</project>
2、准备权限数据
将文件shiro.ini放入resources资源文件件中:
# -----------------------------------------------------------------------------
# 用户,角色,权限,资源
# users:以下都是用户
# root:用户名 ok:密码 admin:角色
# -----------------------------------------------------------------------------
[users]
root = ok,admin
guest = guest,guest
gu = ok,it
# -----------------------------------------------------------------------------
# roles:角色
# admin = * 表示admin角色可以做任何事
# it = employee:save 表示it部可以添加员工
# -----------------------------------------------------------------------------
[roles]
admin = *
guest = employee:*
it = employee:save
3、测试代码
public class ShiroTest {
@Test
public void testShiro(){
/*创建权限管理器工厂*/
IniSecurityManagerFactory iniSecurityManagerFactory = new IniSecurityManagerFactory();
/*获取权限管理器*/
SecurityManager securityManager = iniSecurityManagerFactory.getInstance();
/*把权限管理器放入工具类*/
SecurityUtils.setSecurityManager(securityManager);
/*获取当前用户*/
Subject subject = SecurityUtils.getSubject();
/*判断当前用户是否登录*/
System.out.println(subject.isAuthenticated());
/*
* UnknownAccountException用户名不存在异常
*IncorrectCredentialsException密码错误异常
* AuthenticationException身份验证所有异常
* */
if(!subject.isAuthenticated()){
try {
/*获取令牌*/
UsernamePasswordToken token = new UsernamePasswordToken("admin", "ok");
/*登录*/
subject.login(token);
System.out.println("当前用户是否登录:"+subject.isAuthenticated());
} catch (UnknownAccountException e) {
System.out.println("用户名错误");
e.printStackTrace();
}catch (IncorrectCredentialsException e){
System.out.println("密码错误");
e.printStackTrace();
}catch (AuthenticationException e){
System.out.println("登录出错");
}
}
/*判断当前用户是否有角色*/
System.out.println("是否有admin角色:"+subject.hasRole("admin"));
/*判断当前用户是否有权限*/
System.out.println("是否有departgment:save权限:"+subject.isPermitted("employee:save"));
/*注销,登出*/
subject.logout();
System.out.println("当前用户是否登录:"+subject.isAuthenticated());
}
}
4、shiro身份验证(登录验证)
1、自定义Realm
public class MyRealm extends AuthorizingRealm {
public Set<String> findRole(){
HashSet<String> set = new HashSet<String>();
set.add("admin");
set.add("qq");
return set;
}
public Set<String> findParms(){
HashSet<String> set = new HashSet<String>();
set.add("employee:save");
set.add("department:del");
return set;
}
public String getName(){
return "MyRealm";
}
/*授权*/
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
/*创建授权对象*/
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
/*设置角色*/
Set<String> roles = findRole();
authorizationInfo.setRoles(roles);
/*设置权限*/
Set<String> parms = findParms();
authorizationInfo.setStringPermissions(parms);
return authorizationInfo;
}
/*登录*/
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
/*获取令牌*/
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
/*获取用户名*/
String username = token.getUsername();
/*查询用户密码*/
String password = findByusername(username);
if(password==null)
return null;
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, password, getName());
return authenticationInfo;
}
/*模拟通过用户名查询密码*/
public String findByusername(String username){
if("admin".equals(username))
return "49e14e8b464fbc55da94f2c5ac19ddfd";
else if("root".equals(username))
return "ojbk";
return null;
}
}
2、测试代码
public class MyRealmTest {
@Test
public void testRealm(){
/*获取权限管理器*/
DefaultSecurityManager securityManager = new DefaultSecurityManager();
/*创建自定义Realm*/
MyRealm myRealm = new MyRealm();
/*创建凭证匹配器*/
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
/*设置加密算法*/
matcher.setHashAlgorithmName("MD5");
/*设置迭代次数*/
matcher.setHashIterations(10);
/*设置凭证匹配器规则*/
myRealm.setCredentialsMatcher(matcher);
/*把自定义的realm放入权限管理器*/
securityManager.setRealm(myRealm);
/*把权限管理器放入工具*/
SecurityUtils.setSecurityManager(securityManager);
/*获取当前用户*/
Subject subject = SecurityUtils.getSubject();
/*
* UnknownAccountException用户名不存在异常
*IncorrectCredentialsException密码错误异常
* */
if(!subject.isAuthenticated()){
try {
/*获取令牌*/
UsernamePasswordToken token = new UsernamePasswordToken("admin", "ok");
/*登录*/
subject.login(token);
System.out.println("当前用户是否登录:"+subject.isAuthenticated());
} catch (UnknownAccountException e) {
System.out.println("用户名错误");
e.printStackTrace();
}catch (IncorrectCredentialsException e){
System.out.println("密码错误");
e.printStackTrace();
}catch (AuthenticationException e){
System.out.println("登录出错");
}
}
/*判断当前用户是否有角色*/
System.out.println("是否有admin角色:"+subject.hasRole("admin"));
/*判断当前用户是否有权限*/
System.out.println("是否有departgment:save权限:"+subject.isPermitted("employee:save"));
/*注销,登出*/
/*subject.logout();
System.out.println("当前用户是否登录:"+subject.isAuthenticated());*/
}
/*加密*/
@Test
public void testMD5(){
SimpleHash hash = new SimpleHash("MD5","ok","",10);
System.out.println(hash.toHex());
}
}