1.导入基于Shiro的数据库脚本
例如:
t_sys_user
t_sys_role
t_sys_permission
t_sys_user_role
t_sys_role_permission
关联关系:
用户与角色 角色与权限
用户--------------角色---------------权限
2.自定义Realm
Shiro从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源。
最基础的是Realm接口,CachingRealm负责缓存处理,AuthenticationRealm负责认证,AuthorizingRealm负责授权。
通常自定义的realm继承AuthorizingRealm
注1:体系结构见“shiro提供的realm.png”
AuthorizationInfo:授权信息
AuthenticationInfo:认证信息
3.Spring与Shiro集成
配置自定义Realm
//注入UserService实现类,通过账号密码登录时实现基于Shiro身份认证识别
//盐加密算法配置,详见7.2
注册安全管理器
将自定义的Realm设置到Shiro的SecurityManager中,在Shiro授权和认证时使用自定义的Realm数据源进行校验
filterChainDefinitions Shiro过滤链定义类型:
(1) anon,authcBasic,auchc,user是认证过滤器
(2) perms,roles,ssl,rest,port是授权过滤器
4.修改web.xml文件,添加shiroFilter的配置
注:使用的代理类DelegatingFilterProxy
如:
shiroFilter
org.springframework.web.filter.DelegatingFilterProxy
targetFilterLifecycle
true
shiroFilter
/*
5.创建LoginController实现Shiro身份认证登录
//用户登录
public String login(请求参数){
…
//关键代码
Subject subject=SecurityUtils.getSubject();
UsernamepasswordToken token=new UsernamepasswordToken(
账号,
密码
);
subject.login(token);
…
}
//退出登录
public String logout(){
…
//关键代码
Subject subject=SecurityUtils.getSubject();
subject.logout();
…
}
6.创建login.jsp
7.盐加密
md5
7.1 生成加密密码PasswordHelper类(盐加密)
MD5+散列1024+Hex/Base64
如:
package com.zking.ssm.util;
import org.apache.shiro.crypto.RandomNumberGenerator;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.SimpleHash;
/**
* 用于shiro权限认证的密码工具类
*/
public class PasswordHelper {
/**
* 随机数生成器
*/
private static RandomNumberGenerator randomNumberGenerator = new SecureRandomNumberGenerator();
/**
* 指定hash算法为MD5
*/
private static final String hashAlgorithmName = "md5";
/**
* 指定散列次数为1024次,即加密1024次
*/
private static final int hashIterations = 1024;
/**
* true指定Hash散列值使用Hex(十六进制)加密存. false表明hash散列值用用Base64-encoded存储
* 嵌入式编程
*/
private static final boolean storedCredentialsHexEncoded = true;
/**
* 获得加密用的盐
*
* @return
*/
public static String createSalt() {
return randomNumberGenerator.nextBytes().toHex();
}
/**
* 获得加密后的凭证
*
* @param credentials 凭证(即密码)
* @param salt 盐
* @return
*/
public static String createCredentials(String credentials, String salt) {
SimpleHash simpleHash = new SimpleHash(hashAlgorithmName, credentials,
salt, hashIterations);
return storedCredentialsHexEncoded ? simpleHash.toHex() : simpleHash.toBase64();
}
/**
* 进行密码验证
*
* @param credentials 未加密的密码
* @param salt 盐
* @param encryptCredentials 加密后的密码
* @return
*/
public static boolean checkCredentials(String credentials, String salt, String encryptCredentials) {
return encryptCredentials.equals(createCredentials(credentials, salt));
}
public static void main(String[] args) {
//盐
String salt = createSalt();
System.out.println("随机生成的盐:"+salt);
System.out.println(salt.length());
//凭证+盐加密后得到的密码
String credentials = createCredentials("123", salt);
System.out.println("加密后的串:"+credentials);
System.out.println(credentials.length());
boolean b = checkCredentials("123", salt, credentials);
System.out.println(b);
}
}
7.2 修改applicationContext-shirod的自定义Realm配置,增加以下:
ByteSource.Util.bytes(user.getSalt())