shiro:realm域实例2

来源:互联网 发布:base 私有密码算法 编辑:程序博客网 时间:2024/06/03 22:44

首先先贴一下代码结构



1、SQL

drop table if exists sys_users;drop table if exists sys_roles;drop table if exists sys_permissions;drop table if exists sys_users_roles;drop table if exists sys_roles_permissions;create table sys_users (  id bigint auto_increment,  username varchar(100),  password varchar(100),  salt varchar(100),  locked bool default false,  constraint pk_sys_users primary key(id)) charset=utf8 ENGINE=InnoDB;create unique index idx_sys_users_username on sys_users(username);create table sys_roles (  id bigint auto_increment,  role varchar(100),  description varchar(100),  available bool default false,  constraint pk_sys_roles primary key(id)) charset=utf8 ENGINE=InnoDB;create unique index idx_sys_roles_role on sys_roles(role);create table sys_permissions (  id bigint auto_increment,  permission varchar(100),  description varchar(100),  available bool default false,  constraint pk_sys_permissions primary key(id)) charset=utf8 ENGINE=InnoDB;create unique index idx_sys_permissions_permission on sys_permissions(permission);create table sys_users_roles (  user_id bigint,  role_id bigint,  constraint pk_sys_users_roles primary key(user_id, role_id)) charset=utf8 ENGINE=InnoDB;create table sys_roles_permissions (  role_id bigint,  permission_id bigint,  constraint pk_sys_roles_permissions primary key(role_id, permission_id)) charset=utf8 ENGINE=InnoDB;


2、pom.xml

<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.java.shiro</groupId>  <artifactId>Shiro4</artifactId>  <version>0.0.1-SNAPSHOT</version>  <name>Shiro4</name>  <description>Shiro4</description>    <dependencies>        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>4.9</version>            <scope>test</scope>        </dependency>        <dependency>            <groupId>commons-logging</groupId>            <artifactId>commons-logging</artifactId>            <version>1.1.3</version>        </dependency>        <dependency>            <groupId>org.apache.shiro</groupId>            <artifactId>shiro-core</artifactId>            <version>1.2.2</version>        </dependency>        <dependency>            <groupId>mysql</groupId>            <artifactId>mysql-connector-java</artifactId>            <version>5.1.25</version>        </dependency>        <dependency>            <groupId>com.alibaba</groupId>            <artifactId>druid</artifactId>            <version>0.2.23</version>        </dependency>        <dependency>            <groupId>net.sf.ehcache</groupId>            <artifactId>ehcache-core</artifactId>            <version>2.6.6</version>        </dependency>        <dependency>            <groupId>org.springframework</groupId>            <artifactId>spring-jdbc</artifactId>            <version>4.0.0.RELEASE</version>        </dependency>    </dependencies></project>

3、实体类

package com.java.shiro.entity;import java.io.Serializable;public class Permission implements Serializable {    private static final long serialVersionUID = 1L;private Long id;    private String permission; //权限标识 程序中判断使用,如"user:create"    private String description; //权限描述,UI界面显示使用    private Boolean available = Boolean.FALSE; //是否可用,如果不可用将不会添加给用户    public Permission() {    }    public Permission(String permission, String description, Boolean available) {        this.permission = permission;        this.description = description;        this.available = available;    }    public Long getId() {        return id;    }    public void setId(Long id) {        this.id = id;    }    public String getPermission() {        return permission;    }    public void setPermission(String permission) {        this.permission = permission;    }    public String getDescription() {        return description;    }    public void setDescription(String description) {        this.description = description;    }    public Boolean getAvailable() {        return available;    }    public void setAvailable(Boolean available) {        this.available = available;    }    @Override    public boolean equals(Object o) {        if (this == o) return true;        if (o == null || getClass() != o.getClass()) return false;        Permission role = (Permission) o;        if (id != null ? !id.equals(role.id) : role.id != null) return false;        return true;    }    @Override    public int hashCode() {        return id != null ? id.hashCode() : 0;    }    @Override    public String toString() {        return "Role{" +                "id=" + id +                ", permission='" + permission + '\'' +                ", description='" + description + '\'' +                ", available=" + available +                '}';    }}

package com.java.shiro.entity;import java.io.Serializable;public class Role implements Serializable {   private static final long serialVersionUID = 1L;private Long id;    private String role; //角色标识 程序中判断使用,如"admin"    private String description; //角色描述,UI界面显示使用    private Boolean available = Boolean.FALSE; //是否可用,如果不可用将不会添加给用户    public Role() {    }    public Role(String role, String description, Boolean available) {        this.role = role;        this.description = description;        this.available = available;    }    public Long getId() {        return id;    }    public void setId(Long id) {        this.id = id;    }    public String getRole() {        return role;    }    public void setRole(String role) {        this.role = role;    }    public String getDescription() {        return description;    }    public void setDescription(String description) {        this.description = description;    }    public Boolean getAvailable() {        return available;    }    public void setAvailable(Boolean available) {        this.available = available;    }    @Override    public boolean equals(Object o) {        if (this == o) return true;        if (o == null || getClass() != o.getClass()) return false;        Role role = (Role) o;        if (id != null ? !id.equals(role.id) : role.id != null) return false;        return true;    }    @Override    public int hashCode() {        return id != null ? id.hashCode() : 0;    }    @Override    public String toString() {        return "Role{" +                "id=" + id +                ", role='" + role + '\'' +                ", description='" + description + '\'' +                ", available=" + available +                '}';    }}

package com.java.shiro.entity;import java.io.Serializable;public class RolePermssion implements Serializable {private static final long serialVersionUID = 1L;private Long roleId;    private Long permissionId;    public Long getRoleId() {        return roleId;    }    public void setRoleId(Long roleId) {        this.roleId = roleId;    }    public Long getPermissionId() {        return permissionId;    }    public void setPermissionId(Long permissionId) {        this.permissionId = permissionId;    }    @Override    public boolean equals(Object o) {        if (this == o) return true;        if (o == null || getClass() != o.getClass()) return false;        RolePermssion that = (RolePermssion) o;        if (permissionId != null ? !permissionId.equals(that.permissionId) : that.permissionId != null) return false;        if (roleId != null ? !roleId.equals(that.roleId) : that.roleId != null) return false;        return true;    }    @Override    public int hashCode() {        int result = roleId != null ? roleId.hashCode() : 0;        result = 31 * result + (permissionId != null ? permissionId.hashCode() : 0);        return result;    }    @Override    public String toString() {        return "RolePermssion{" +                "roleId=" + roleId +                ", permissionId=" + permissionId +                '}';    }}

package com.java.shiro.entity;import java.io.Serializable;public class User implements Serializable {   private static final long serialVersionUID = 1L;private Long id;//编号    private String username;//用户名    private String password;//密码    private String salt;//盐    private Boolean locked = Boolean.FALSE;//是否锁定    public User() {    }    public User(String username, String password) {        this.username = username;        this.password = password;    }    public Long getId() {        return id;    }    public void setId(Long id) {        this.id = id;    }    public String getUsername() {        return username;    }    public void setUsername(String username) {        this.username = username;    }    public String getPassword() {        return password;    }    public void setPassword(String password) {        this.password = password;    }    public String getSalt() {        return salt;    }    public void setSalt(String salt) {        this.salt = salt;    }    public String getCredentialsSalt() {        return username + salt;    }    public Boolean getLocked() {        return locked;    }    public void setLocked(Boolean locked) {        this.locked = locked;    }    @Override    public boolean equals(Object o) {        if (this == o) return true;        if (o == null || getClass() != o.getClass()) return false;        User user = (User) o;        if (id != null ? !id.equals(user.id) : user.id != null) return false;        return true;    }    @Override    public int hashCode() {        return id != null ? id.hashCode() : 0;    }    @Override    public String toString() {        return "User{" +                "id=" + id +                ", username='" + username + '\'' +                ", password='" + password + '\'' +                ", salt='" + salt + '\'' +                ", locked=" + locked +                '}';    }}

package com.java.shiro.entity;import java.io.Serializable;public class UserRole implements Serializable {private static final long serialVersionUID = 1L;private Long userId;    private Long roleId;    public Long getUserId() {        return userId;    }    public void setUserId(Long userId) {        this.userId = userId;    }    public Long getRoleId() {        return roleId;    }    public void setRoleId(Long roleId) {        this.roleId = roleId;    }    @Override    public boolean equals(Object o) {        if (this == o) return true;        if (o == null || getClass() != o.getClass()) return false;        UserRole userRole = (UserRole) o;        if (roleId != null ? !roleId.equals(userRole.roleId) : userRole.roleId != null) return false;        if (userId != null ? !userId.equals(userRole.userId) : userRole.userId != null) return false;        return true;    }    @Override    public int hashCode() {        int result = userId != null ? userId.hashCode() : 0;        result = 31 * result + (roleId != null ? roleId.hashCode() : 0);        return result;    }    @Override    public String toString() {        return "UserRole{" +                "userId=" + userId +                ", roleId=" + roleId +                '}';    }}

4、Dao及实现类

package com.java.shiro.dao;import com.java.shiro.entity.Permission;public interface PermissionDao {public Permission createPermission(Permission permission);    public void deletePermission(Long permissionId);}

package com.java.shiro.dao.impl;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.PreparedStatementCreator;import org.springframework.jdbc.support.GeneratedKeyHolder;import com.java.shiro.dao.PermissionDao;import com.java.shiro.entity.Permission;import com.java.shiro.util.JdbcTemplateUtils;public class PermissionDaoImpl implements PermissionDao {private JdbcTemplate jdbcTemplate = JdbcTemplateUtils.jdbcTemplate();@Overridepublic Permission createPermission(final Permission permission) {final String sql = "insert into sys_permissions(permission, description, available) values(?,?,?)";GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();jdbcTemplate.update(new PreparedStatementCreator() {@Overridepublic PreparedStatement createPreparedStatement(Connection con) throws SQLException {PreparedStatement psst = con.prepareStatement(sql,new String[]{"id"});psst.setString(1,permission.getPermission());psst.setString(2,permission.getDescription());psst.setBoolean(3,permission.getAvailable());return psst;}}, keyHolder); permission.setId(keyHolder.getKey().longValue());return permission;}@Overridepublic void deletePermission(Long permissionId) {//首先把与permission关联的相关表的数据删掉        String sql = "delete from sys_roles_permissions where permission_id=?";        jdbcTemplate.update(sql, permissionId);        sql = "delete from sys_permissions where id=?";        jdbcTemplate.update(sql, permissionId);}}

package com.java.shiro.dao;import com.java.shiro.entity.Role;public interface RoleDao {public Role createRole(Role role);    public void deleteRole(Long roleId);    public void correlationPermissions(Long roleId, Long... permissionIds);    public void uncorrelationPermissions(Long roleId, Long... permissionIds);}

package com.java.shiro.dao.impl;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.PreparedStatementCreator;import org.springframework.jdbc.support.GeneratedKeyHolder;import com.java.shiro.dao.RoleDao;import com.java.shiro.entity.Role;import com.java.shiro.util.JdbcTemplateUtils;public class RoleDaoImpl implements RoleDao {private JdbcTemplate jdbcTemplate = JdbcTemplateUtils.jdbcTemplate();/** * 新建角色 */@Overridepublic Role createRole(final Role role) {final String sql = "insert into sys_roles(role, description, available) values(?,?,?)";GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();jdbcTemplate.update(new PreparedStatementCreator() {@Overridepublic PreparedStatement createPreparedStatement(Connection con) throws SQLException {PreparedStatement psst = con.prepareStatement(sql, new String[]{"id"});psst.setString(1,role.getRole());psst.setString(2,role.getDescription());psst.setBoolean(3,role.getAvailable());return psst;}}, keyHolder);role.setId(keyHolder.getKey().longValue());return role;}/** * 删除角色 */@Overridepublic void deleteRole(Long roleId) {//首先把和role关联的相关表数据删掉        String sql = "delete from sys_users_roles where role_id=?";        jdbcTemplate.update(sql, roleId);        sql = "delete from sys_roles where id=?";        jdbcTemplate.update(sql, roleId);}/** * 添加角色-权限之间关系 */@Overridepublic void correlationPermissions(Long roleId, Long... permissionIds) {if (permissionIds == null || permissionIds.length == 0) {return;}String sql = "insert into sys_roles_permissions(role_id, permission_id) values(?,?)";for (Long permissionId : permissionIds) {if (!exists(roleId, permissionId)) {jdbcTemplate.update(sql, roleId,permissionId);}}}/** * 移除角色-权限之间关系 */@Overridepublic void uncorrelationPermissions(Long roleId, Long... permissionIds) {if (permissionIds == null || permissionIds.length == 0) {return;}String sql = "delete from sys_roles_permissions where role_id=? and permission_id=?";for (Long permissionId : permissionIds) {if (!exists(roleId, permissionId)) {jdbcTemplate.update(sql, roleId,permissionId);}}} private boolean exists(Long roleId, Long permissionId) {        String sql = "select count(1) from sys_roles_permissions where role_id=? and permission_id=?";        return jdbcTemplate.queryForObject(sql, Integer.class, roleId, permissionId) != 0;    }}

package com.java.shiro.dao;import java.util.Set;import com.java.shiro.entity.User;public interface UserDao {    public User createUser(User user);    public void updateUser(User user);    public void deleteUser(Long userId);    public void correlationRoles(Long userId, Long... roleIds);    public void uncorrelationRoles(Long userId, Long... roleIds);    User findOne(Long userId);    User findByUsername(String username);    Set<String> findRoles(String username);    Set<String> findPermissions(String username);}

package com.java.shiro.dao.impl;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;import java.util.HashSet;import java.util.List;import java.util.Set;import org.springframework.jdbc.core.BeanPropertyRowMapper;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.PreparedStatementCreator;import org.springframework.jdbc.support.GeneratedKeyHolder;import com.java.shiro.dao.UserDao;import com.java.shiro.entity.User;import com.java.shiro.util.JdbcTemplateUtils;public class UserDaoImpl implements UserDao {private JdbcTemplate jdbcTemplate = JdbcTemplateUtils.jdbcTemplate();/** * 新增用户 */@Overridepublic User createUser(final User user) {final String sql = "insert into sys_users(username, password, salt, locked) values(?,?,?, ?)";GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();jdbcTemplate.update(new PreparedStatementCreator() {@Overridepublic PreparedStatement createPreparedStatement(Connection con)throws SQLException {PreparedStatement psst = con.prepareStatement(sql, new String[]{"id"});psst.setString(1,user.getUsername());psst.setString(2,user.getPassword());psst.setString(3,user.getSalt());psst.setBoolean(4,user.getLocked());return psst;}}, keyHolder);user.setId(keyHolder.getKey().longValue());return user;}/** * 更新用户 */@Overridepublic void updateUser(User user) {String sql = "update sys_users set username=?, password=?, salt=?, locked=? where id=?";jdbcTemplate.update(sql, user.getUsername(),user.getPassword(),user.getSalt(),user.getLocked(),user.getId());}/** * 删除用户 */@Overridepublic void deleteUser(Long userId) {String sql = "delete from sys_users where id=?";        jdbcTemplate.update(sql, userId);}/** * 添加用户-角色关系 */@Overridepublic void correlationRoles(Long userId, Long... roleIds) {if (roleIds == null  || roleIds.length == 0) {return;}String sql = "insert into sys_users_roles(user_id, role_id) values(?,?)";for (Long roleId : roleIds) {if (!exists(userId, roleId)) {jdbcTemplate.update(sql, userId,roleId);}}}/** * 移除用户-角色关系   */@Overridepublic void uncorrelationRoles(Long userId, Long... roleIds) {if (roleIds == null || roleIds.length == 0) {return;}String sql = "delete from sys_users_roles where user_id=? and role_id=?";for (Long roleId : roleIds) {if (!exists(userId, roleId)) {jdbcTemplate.update(sql, userId,roleId);}}}/** * 根据 userId 获取用户 */@Overridepublic User findOne(Long userId) {String sql = "select id, username, password, salt, locked from sys_users where id=?";        List<User> userList = jdbcTemplate.query(sql, new BeanPropertyRowMapper(User.class), userId);        if(userList.size() == 0) {            return null;        }        return userList.get(0);}/** * 根据 username 获取用户 */@Overridepublic User findByUsername(String username) {String sql = "select id, username, password, salt, locked from sys_users where username=?";        List<User> userList = jdbcTemplate.query(sql, new BeanPropertyRowMapper(User.class), username);        if(userList.size() == 0) {            return null;        }        return userList.get(0);}/** * 根据 username 获取用户角色 */@Overridepublic Set<String> findRoles(String username) {String sql = "select role from sys_users u, sys_roles r,sys_users_roles ur where u.username=? and u.id=ur.user_id and r.id=ur.role_id";        return new HashSet(jdbcTemplate.queryForList(sql, String.class, username));}/** * 根据 username 获取用户权限 */@Overridepublic Set<String> findPermissions(String username) {//TODO 此处可以优化,比如查询到role后,一起获取roleId,然后直接根据roleId获取即可        String sql = "select permission from sys_users u, sys_roles r, sys_permissions p, sys_users_roles ur, sys_roles_permissions rp where u.username=? and u.id=ur.user_id and r.id=ur.role_id and r.id=rp.role_id and p.id=rp.permission_id";        return new HashSet(jdbcTemplate.queryForList(sql, String.class, username));}private boolean exists(Long userId, Long roleId) {        String sql = "select count(1) from sys_users_roles where user_id=? and role_id=?";        return jdbcTemplate.queryForObject(sql, Integer.class, userId, roleId) != 0;    }}

5、service及实现类

package com.java.shiro.service;import com.java.shiro.entity.Permission;public interface PermissionService {public Permission createPermission(Permission permission);    public void deletePermission(Long permissionId);}

package com.java.shiro.service.impl;import com.java.shiro.dao.PermissionDao;import com.java.shiro.dao.impl.PermissionDaoImpl;import com.java.shiro.entity.Permission;import com.java.shiro.service.PermissionService;public class PermissionServiceImpl implements PermissionService{private PermissionDao permissionDao = new PermissionDaoImpl();@Override    public Permission createPermission(Permission permission) {        return permissionDao.createPermission(permission);    }@Override    public void deletePermission(Long permissionId) {        permissionDao.deletePermission(permissionId);    }}

package com.java.shiro.service;import com.java.shiro.entity.Role;public interface RoleService {public Role createRole(Role role);    public void deleteRole(Long roleId);    /**     * 添加角色-权限之间关系     * @param roleId     * @param permissionIds     */    public void correlationPermissions(Long roleId, Long... permissionIds);    /**     * 移除角色-权限之间关系     * @param roleId     * @param permissionIds     */    public void uncorrelationPermissions(Long roleId, Long... permissionIds);}

package com.java.shiro.service.impl;import com.java.shiro.dao.RoleDao;import com.java.shiro.dao.impl.RoleDaoImpl;import com.java.shiro.entity.Role;import com.java.shiro.service.RoleService;public class RoleServiceImpl implements RoleService{private RoleDao roleDao = new RoleDaoImpl();@Override    public Role createRole(Role role) {        return roleDao.createRole(role);    }@Override    public void deleteRole(Long roleId) {        roleDao.deleteRole(roleId);    }    /**     * 添加角色-权限之间关系     * @param roleId     * @param permissionIds     */@Override    public void correlationPermissions(Long roleId, Long... permissionIds) {        roleDao.correlationPermissions(roleId, permissionIds);    }    /**     * 移除角色-权限之间关系     * @param roleId     * @param permissionIds     */@Override    public void uncorrelationPermissions(Long roleId, Long... permissionIds) {        roleDao.uncorrelationPermissions(roleId, permissionIds);    }}

package com.java.shiro.service;import java.util.Set;import com.java.shiro.entity.User;public interface UserService {    /**     * 创建用户     * @param user     */    public User createUser(User user);    /**     * 修改密码     * @param userId     * @param newPassword     */    public void changePassword(Long userId, String newPassword);    /**     * 添加用户-角色关系     * @param userId     * @param roleIds     */    public void correlationRoles(Long userId, Long... roleIds);    /**     * 移除用户-角色关系     * @param userId     * @param roleIds     */    public void uncorrelationRoles(Long userId, Long... roleIds);    /**     * 根据用户名查找用户     * @param username     * @return     */    public User findByUsername(String username);    /**     * 根据用户名查找其角色     * @param username     * @return     */    public Set<String> findRoles(String username);    /**     * 根据用户名查找其权限     * @param username     * @return     */    public Set<String> findPermissions(String username);}

package com.java.shiro.service.impl;import java.util.Set;import com.java.shiro.dao.UserDao;import com.java.shiro.dao.impl.UserDaoImpl;import com.java.shiro.entity.User;import com.java.shiro.service.UserService;import com.java.shiro.util.PasswordHelper;public class UserServiceImpl implements UserService{private UserDao userDao = new UserDaoImpl();    private PasswordHelper passwordHelper = new PasswordHelper();    /**     * 创建用户     * @param user     */    public User createUser(User user) {        //加密密码        passwordHelper.encryptPassword(user);        return userDao.createUser(user);    }    /**     * 修改密码     * @param userId     * @param newPassword     */    public void changePassword(Long userId, String newPassword) {        User user =userDao.findOne(userId);        user.setPassword(newPassword);        passwordHelper.encryptPassword(user);        userDao.updateUser(user);    }    /**     * 添加用户-角色关系     * @param userId     * @param roleIds     */    public void correlationRoles(Long userId, Long... roleIds) {        userDao.correlationRoles(userId, roleIds);    }    /**     * 移除用户-角色关系     * @param userId     * @param roleIds     */    public void uncorrelationRoles(Long userId, Long... roleIds) {        userDao.uncorrelationRoles(userId, roleIds);    }    /**     * 根据用户名查找用户     * @param username     * @return     */    public User findByUsername(String username) {        return userDao.findByUsername(username);    }    /**     * 根据用户名查找其角色     * @param username     * @return     */    public Set<String> findRoles(String username) {        return userDao.findRoles(username);    }    /**     * 根据用户名查找其权限     * @param username     * @return     */    public Set<String> findPermissions(String username) {        return userDao.findPermissions(username);    }}

6、公共类

package com.java.shiro.util;import org.springframework.jdbc.core.JdbcTemplate;import com.alibaba.druid.pool.DruidDataSource;public class JdbcTemplateUtils {private static JdbcTemplate jdbcTemplate;private static JdbcTemplate createJdbcTemplate(){DruidDataSource pool = new DruidDataSource();pool.setDriverClassName("com.mysql.jdbc.Driver");pool.setUrl("jdbc:mysql://localhost:3306/db_shiro");pool.setUsername("root");pool.setPassword("root");return new JdbcTemplate(pool);}public static JdbcTemplate jdbcTemplate(){if (jdbcTemplate == null) {jdbcTemplate = createJdbcTemplate();}return jdbcTemplate;}}

package com.java.shiro.util;import org.apache.shiro.crypto.RandomNumberGenerator;import org.apache.shiro.crypto.SecureRandomNumberGenerator;import org.apache.shiro.crypto.hash.SimpleHash;import org.apache.shiro.util.ByteSource;import com.java.shiro.entity.User;public class PasswordHelper {private RandomNumberGenerator randomNumberGenerator = new SecureRandomNumberGenerator();private String algorithmName = "md5";private final int hashIterations = 2;public void encryptPassword(User user) {        user.setSalt(randomNumberGenerator.nextBytes().toHex());        String newPassword = new SimpleHash(algorithmName,user.getPassword(),ByteSource.Util.bytes(user.getCredentialsSalt()),hashIterations).toHex();        user.setPassword(newPassword);    }}

7、自定义 realm

package com.java.shiro.realm;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.realm.Realm;public class MyRealm1 implements Realm{ @Override    public String getName() {        return "a"; //realm name 为 “a”    }    @Override    public boolean supports(AuthenticationToken token) {        return token instanceof UsernamePasswordToken;    }    @Override    public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {        return new SimpleAuthenticationInfo(                "zhang", //身份 字符串类型                "123",   //凭据                getName() //Realm Name        );    }}

package com.java.shiro.realm;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.realm.Realm;public class MyRealm2 implements Realm{    @Override    public String getName() {        return "b"; //realm name 为 “b”    }    @Override    public boolean supports(AuthenticationToken token) {        return token instanceof UsernamePasswordToken;    }    @Override    public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {        return new SimpleAuthenticationInfo(                "zhang", //身份 字符串类型                "123",   //凭据                getName() //Realm Name        );    }}

package com.java.shiro.realm;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.realm.Realm;import com.java.shiro.entity.User;public class MyRealm3 implements Realm{    @Override    public String getName() {        return "c"; //realm name 为 “c”    }    @Override    public boolean supports(AuthenticationToken token) {        return token instanceof UsernamePasswordToken;    }    @Override    public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {        User user = new User("zhang", "123");        return new SimpleAuthenticationInfo(                user, //身份 User类型                "123",   //凭据                getName() //Realm Name        );    }}

package com.java.shiro.realm;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.LockedAccountException;import org.apache.shiro.authc.SimpleAccount;import org.apache.shiro.authc.UnknownAccountException;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import org.apache.shiro.util.ByteSource;import com.java.shiro.entity.User;import com.java.shiro.service.UserService;import com.java.shiro.service.impl.UserServiceImpl;public class UserRealm extends AuthorizingRealm {private UserService userService = new UserServiceImpl();/** * 授权 */@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {String username = (String) principals.getPrimaryPrincipal();SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();authorizationInfo.setRoles(userService.findRoles(username));authorizationInfo.setStringPermissions(userService.findPermissions(username));return authorizationInfo;}/** * 验证 */@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {String username =(String)token.getPrincipal();User user = userService.findByUsername(username);if (user == null) {throw new UnknownAccountException();//没有找到账号}if (Boolean.TRUE.equals(user.getLocked())) {throw new LockedAccountException();//账号已锁定}AuthenticationInfo authenticationInfo = new SimpleAccount(user.getUsername(),//用户名user.getPassword(),//密码ByteSource.Util.bytes(user.getCredentialsSalt()),//salt=username+saltgetName());return authenticationInfo;}}

8、资质认证

package com.java.shiro.credentials;import java.util.concurrent.atomic.AtomicInteger;import net.sf.ehcache.CacheManager;import net.sf.ehcache.Ehcache;import net.sf.ehcache.Element;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.ExcessiveAttemptsException;import org.apache.shiro.authc.credential.HashedCredentialsMatcher;public class RetryLimitHashedCredentialsMatcher extends HashedCredentialsMatcher{    private Ehcache passwordRetryCache;    public RetryLimitHashedCredentialsMatcher() {        CacheManager cacheManager = CacheManager.newInstance(CacheManager.class.getClassLoader().getResource("ehcache.xml"));        passwordRetryCache = cacheManager.getCache("passwordRetryCache");    }    @Override    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {        String username = (String)token.getPrincipal();        //retry count + 1        Element element = passwordRetryCache.get(username);        if(element == null) {            element = new Element(username , new AtomicInteger(0));            passwordRetryCache.put(element);        }        AtomicInteger retryCount = (AtomicInteger)element.getObjectValue();        if(retryCount.incrementAndGet() > 5) {            //if retry count > 5 throw            throw new ExcessiveAttemptsException();        }        boolean matches = super.doCredentialsMatch(token, info);        if(matches) {            //clear retry count            passwordRetryCache.remove(username);        }        return matches;    }}

9、配置文件

ehcache.xml

<?xml version="1.0" encoding="UTF-8"?><ehcache name="es">    <diskStore path="java.io.tmpdir"/>    <!-- 登录记录缓存 锁定10分钟 -->    <cache name="passwordRetryCache"           maxEntriesLocalHeap="2000"           eternal="false"           timeToIdleSeconds="3600"           timeToLiveSeconds="0"           overflowToDisk="false"           statistics="true">    </cache></ehcache>

shiro-multirealm.ini

[main]realm1=com.java.shiro.realm.MyRealm1realm2=com.java.shiro.realm.MyRealm2realm3=com.java.shiro.realm.MyRealm3securityManager.realms=$realm1,$realm2,$realm3

shiro.ini

[main]credentialsMatcher=com.java.shiro.credentials.RetryLimitHashedCredentialsMatchercredentialsMatcher.hashAlgorithmName=md5credentialsMatcher.hashIterations=2credentialsMatcher.storedCredentialsHexEncoded=trueuserRealm=com.java.shiro.realm.UserRealmuserRealm.credentialsMatcher=$credentialsMatchersecurityManager.realms=$userRealm

10、测试

package BaseTest;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.config.IniSecurityManagerFactory;import org.apache.shiro.subject.Subject;import org.apache.shiro.util.Factory;import org.apache.shiro.util.ThreadContext;import org.junit.After;import org.junit.Before;import com.java.shiro.entity.Permission;import com.java.shiro.entity.Role;import com.java.shiro.entity.User;import com.java.shiro.service.PermissionService;import com.java.shiro.service.RoleService;import com.java.shiro.service.UserService;import com.java.shiro.service.impl.PermissionServiceImpl;import com.java.shiro.service.impl.RoleServiceImpl;import com.java.shiro.service.impl.UserServiceImpl;import com.java.shiro.util.JdbcTemplateUtils;import org.apache.shiro.mgt.SecurityManager;public class BaseTest {    protected PermissionService permissionService = new PermissionServiceImpl();    protected RoleService roleService = new RoleServiceImpl();    protected UserService userService = new UserServiceImpl();    protected String password = "123";    protected Permission p1;    protected Permission p2;    protected Permission p3;    protected Role r1;    protected Role r2;    protected User u1;    protected User u2;    protected User u3;    protected User u4;    @Before    public void setUp() {        JdbcTemplateUtils.jdbcTemplate().update("delete from sys_users");        JdbcTemplateUtils.jdbcTemplate().update("delete from sys_roles");        JdbcTemplateUtils.jdbcTemplate().update("delete from sys_permissions");        JdbcTemplateUtils.jdbcTemplate().update("delete from sys_users_roles");        JdbcTemplateUtils.jdbcTemplate().update("delete from sys_roles_permissions");        //1、新增权限        p1 = new Permission("user:create", "用户模块新增", Boolean.TRUE);        p2 = new Permission("user:update", "用户模块修改", Boolean.TRUE);        p3 = new Permission("menu:create", "菜单模块新增", Boolean.TRUE);        permissionService.createPermission(p1);        permissionService.createPermission(p2);        permissionService.createPermission(p3);        //2、新增角色        r1 = new Role("admin", "管理员", Boolean.TRUE);        r2 = new Role("user", "用户管理员", Boolean.TRUE);        roleService.createRole(r1);        roleService.createRole(r2);        //3、关联角色-权限        roleService.correlationPermissions(r1.getId(), p1.getId());        roleService.correlationPermissions(r1.getId(), p2.getId());        roleService.correlationPermissions(r1.getId(), p3.getId());        roleService.correlationPermissions(r2.getId(), p1.getId());        roleService.correlationPermissions(r2.getId(), p2.getId());        //4、新增用户        u1 = new User("zhang", password);        u2 = new User("li", password);        u3 = new User("wu", password);        u4 = new User("wang", password);        u4.setLocked(Boolean.TRUE);        userService.createUser(u1);        userService.createUser(u2);        userService.createUser(u3);        userService.createUser(u4);        //5、关联用户-角色        userService.correlationRoles(u1.getId(), r1.getId());    }    @After    public void tearDown() throws Exception {        ThreadContext.unbindSubject();//退出时请解除绑定Subject到线程 否则对下次测试造成影响    }    protected void login(String configFile, String username, String password) {        //1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager        Factory<SecurityManager> factory = new IniSecurityManagerFactory(configFile);        //2、得到SecurityManager实例 并绑定给SecurityUtils        SecurityManager securityManager = factory.getInstance();        SecurityUtils.setSecurityManager(securityManager);        //3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证)        Subject subject = SecurityUtils.getSubject();        UsernamePasswordToken token = new UsernamePasswordToken(username, password);        subject.login(token);    }    public Subject subject() {        return SecurityUtils.getSubject();    }}

package realm;import java.util.Collection;import java.util.Set;import junit.framework.Assert;import org.apache.shiro.subject.PrincipalCollection;import org.apache.shiro.subject.Subject;import org.junit.Test;import com.java.shiro.entity.User;import BaseTest.BaseTest;public class PrincialCollectionTest extends BaseTest{    @Test    public void test() {        //因为Realm里没有进行验证,所以相当于每个Realm都身份验证成功了        login("classpath:shiro-multirealm.ini", "zhang", "123");        Subject subject = subject();        //获取Primary Principal(即第一个)        Object primaryPrincipal1 = subject.getPrincipal();        PrincipalCollection princialCollection = subject.getPrincipals();        Object primaryPrincipal2 = princialCollection.getPrimaryPrincipal();        //但是因为多个Realm都返回了Principal,所以此处到底是哪个是不确定的        Assert.assertEquals(primaryPrincipal1, primaryPrincipal2);        //返回 a b c        Set<String> realmNames = princialCollection.getRealmNames();        System.out.println(realmNames);        //因为MyRealm1和MyRealm2返回的凭据都是zhang,所以排重了        Set<Object> principals = princialCollection.asSet(); //asList和asSet的结果一样        System.out.println(principals);        //根据Realm名字获取        Collection<User> users = princialCollection.fromRealm("c");        System.out.println(users);    }}

package realm;import junit.framework.Assert;import org.junit.Test;import org.apache.shiro.authc.ExcessiveAttemptsException;import org.apache.shiro.authc.IncorrectCredentialsException;import org.apache.shiro.authc.LockedAccountException;import org.apache.shiro.authc.UnknownAccountException;import BaseTest.BaseTest;public class UserRealmTest extends BaseTest{    @Test    public void testLoginSuccess() {      login("classpath:shiro.ini", u1.getUsername(), password);      Assert.assertTrue(subject().isAuthenticated());  }  @Test(expected = UnknownAccountException.class)  public void testLoginFailWithUnknownUsername() {      login("classpath:shiro.ini", u1.getUsername() + "1", password);  }  @Test(expected = IncorrectCredentialsException.class)  public void testLoginFailWithErrorPassowrd() {      login("classpath:shiro.ini", u1.getUsername(), password + "1");  }  @Test(expected = LockedAccountException.class)  public void testLoginFailWithLocked() {      login("classpath:shiro.ini", u4.getUsername(), password + "1");  }  @Test(expected = ExcessiveAttemptsException.class)  public void testLoginFailWithLimitRetryCount() {      for(int i = 1; i <= 5; i++) {          try {              login("classpath:shiro.ini", u3.getUsername(), password + "1");          } catch (Exception e) {/*ignore*/}      }      login("classpath:shiro.ini", u3.getUsername(), password + "1");      //需要清空缓存,否则后续的执行就会遇到问题(或者使用一个全新账户测试)  }  @Test  public void testHasRole() {      login("classpath:shiro.ini", u1.getUsername(), password );      Assert.assertTrue(subject().hasRole("admin"));  }  @Test  public void testNoRole() {      login("classpath:shiro.ini", u2.getUsername(), password);      Assert.assertFalse(subject().hasRole("admin"));  }  @Test  public void testHasPermission() {      login("classpath:shiro.ini", u1.getUsername(), password);      Assert.assertTrue(subject().isPermittedAll("user:create", "menu:create"));  }  @Test  public void testNoPermission() {      login("classpath:shiro.ini", u2.getUsername(), password);      Assert.assertFalse(subject().isPermitted("user:create"));  }}

package service;import java.util.Set;import junit.framework.Assert;import org.junit.Test;import BaseTest.BaseTest;public class ServiceTest extends BaseTest {    @Test    public void testUserRolePermissionRelation() {        //zhang        Set<String> roles = userService.findRoles(u1.getUsername());        Assert.assertEquals(1, roles.size());        Assert.assertTrue(roles.contains(r1.getRole()));        Set<String> permissions = userService.findPermissions(u1.getUsername());        Assert.assertEquals(3, permissions.size());        Assert.assertTrue(permissions.contains(p3.getPermission()));        //li        roles = userService.findRoles(u2.getUsername());        Assert.assertEquals(0, roles.size());        permissions = userService.findPermissions(u2.getUsername());        Assert.assertEquals(0, permissions.size());        //解除 admin-menu:update关联        roleService.uncorrelationPermissions(r1.getId(), p3.getId());        permissions = userService.findPermissions(u1.getUsername());        Assert.assertEquals(2, permissions.size());        Assert.assertFalse(permissions.contains(p3.getPermission()));        //删除一个permission        permissionService.deletePermission(p2.getId());        permissions = userService.findPermissions(u1.getUsername());        Assert.assertEquals(1, permissions.size());        //解除 zhang-admin关联        userService.uncorrelationRoles(u1.getId(), r1.getId());        roles = userService.findRoles(u1.getUsername());        Assert.assertEquals(0, roles.size());    }}

这是根据《跟我学shiro》写的代码,觉得挺有用的。


到此结束啦~~

原创粉丝点击