Realm中认证和授权数据从数据库获取:
表结构
用户表:sys_user:
角色表:sys_role:
中间表:sys_user_role:
资源表:sys_resource
中间表:sys_role_resource:
UserMapper.java
public interface UserMapper {
......
/**
* 根据用户id获取用户的角色名称集合
* @param userId
* @return
*/
Set<String> selectUserRoleSet(Integer userId);
/**
* 根据用户id获取用户的权限名称集合
* @param userId
* @return
*/
Set<String> selectUserPermissionSet(Integer userId);
}
UserMapper.xml
<select id="selectUserRoleNameSet" resultType="java.lang.String"
parameterType="java.lang.Integer">
SELECT DISTINCT
t1.name
FROM
sys_role t1,
sys_user_role t2
WHERE
t1.role_id = t2.role_id
AND t2.user_id = #{userId}
</select>
<select id="selectUserPermissionNameSet" resultType="java.lang.String"
parameterType="java.lang.Integer">
SELECT DISTINCT
t1.permission
FROM
sys_resource t1,
sys_role_resource t2,
sys_user_role t3
WHERE t1.permission IS NOT NULL
AND t1.resource_id = t2.resource_id
AND t2.role_id = t3.role_id
AND t3.user_id = #{userId}
</select>
ShiroRealm
public class ShiroRealm extends AuthorizingRealm {
@Autowired
private UserMapper userMapper;
/**
* 认证
*
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
throws AuthenticationException {
System.out.println("认证...");
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
//1.获取主体信息
String username = token.getUsername();
//2.获取凭证信息
String password = new String(token.getPassword());
//3.获取用户信息
UserExample param = new UserExample();
param.createCriteria().andUsernameEqualTo(username);
User user = null;
try {
user = userMapper.selectByExample(param).get(0);
} catch (Exception e) {
}
if (user == null) {
throw new UnknownAccountException("用户名或密码错误");
}
String db_password = user.getPassword();// 数据库存储的密码
if (!db_password.equals(password)) {
throw new IncorrectCredentialsException("密码错误");
}
SimpleAuthenticationInfo info =
new SimpleAuthenticationInfo(user, token.getCredentials(), getName());
return info;
}
/**
* 授权检查
*
* @param principals
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
System.out.println("授权...");
User user = (User) principals.getPrimaryPrincipal(); //
// 通过用户名去数据库查询该用户有哪些角色和权限
// 创建简单授权信息对象
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// 设置角色信息
Set<String> roles =
userMapper.selectUserRoleNameSet(user.getUserId());
info.addRoles(roles);
// 设置权限信息
Set<String> permissionSet =
userMapper.selectUserPermissionNameSet(user.getUserId());
Set<String> permissions = new HashSet<>();
for (String item : permissionSet) {
for (String p : item.split(",")) {
permissions.add(p);
}
}
info.addStringPermissions(permissions);
return info;
}
}
测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring-config.xml")
public class ShiroTest {
@Autowired
private SecurityManager securityManager;
@Test
public void test(){
String username = "admin";
//对密码进行加密
String password = MD5Util.md5("123456","ak47");
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
SecurityUtils.getSubject().login(token);
Subject subject = SecurityUtils.getSubject();
System.out.println(subject.hasRole("系统管理员"));
System.out.println(subject.isPermitted("sys:user:list"));
// 退出登录
subject.logout();
}
}