一、新建SpringBoot项目
添加SpringBoot相关依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
二、添加Shiro依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
三、建立权限相关表(五表权限设计)
create table user(
id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(20) NOT NULL ,
password VARCHAR(20) not null
);
create table role(
id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
rolename VARCHAR(20) NOT NULL,
roledesc VARCHAR(20)
);
create table permission(
id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
modelname VARCHAR(20) NOT NULL ,
permission VARCHAR(20) NOT NULL
);
create table user_role(
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
uid int NOT NULL ,
rid int NOT NULL
);
create table role_permission(
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
rid int NOT NULL ,
pid int NOT NULL
);
四、Shiro配置
@Configuration
public class ShiroConfig {
public ShiroConfig(){
System.out.println("ShiroConfig init ....");
}
/**
shiro过滤器配置
*/
@Bean
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
System.out.println("ShiroConfiguration.shirFilter()");
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
//拦截器.
Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
//权限配置
//filterChainDefinitionMap.put("/stu/addStu","perms[student:aaaa]");
// 配置不会被拦截的链接 顺序判断 相关静态资源
filterChainDefinitionMap.put("/assets/**", "anon");
filterChainDefinitionMap.put("/css/**", "anon");
filterChainDefinitionMap.put("/font/**", "anon");
filterChainDefinitionMap.put("/images/**", "anon");
filterChainDefinitionMap.put("/js/**", "anon");
filterChainDefinitionMap.put("/products/**", "anon");
filterChainDefinitionMap.put("/Widget/**", "anon");
//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
filterChainDefinitionMap.put("/logout", "logout");
//<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
//<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
filterChainDefinitionMap.put("/**", "authc");
// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
shiroFilterFactoryBean.setLoginUrl("/login");
// 登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl("/index");
//未授权界面;
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
/*
加密方式配置
*/
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher(){
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;
hashedCredentialsMatcher.setHashIterations(2);//散列的次数,比如散列两次,相当于 md5(md5(""));
return hashedCredentialsMatcher;
}
/*
认证器配置
*/
@Bean
public MyShiroRelam myShiroRealm(){
MyShiroRelam myShiroRelam = new MyShiroRelam();
//myShiroRelam.setCredentialsMatcher(hashedCredentialsMatcher());
return myShiroRelam;
}
/*
安全管理器配置
*/
@Bean
public SecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
return securityManager;
}
/*
开启@RequirePermission注解的配置,要结合DefaultAdvisorAutoProxyCreator一起使用,或者导入aop的依赖
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
/* @Bean
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
advisorAutoProxyCreator.setProxyTargetClass(true);
return advisorAutoProxyCreator;
}*/
/*
定义Spring MVC的异常处理器
*/
@Bean
public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver() {
SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver();
Properties mappings = new Properties();
mappings.setProperty("DatabaseException", "databaseError");//数据库异常处理
mappings.setProperty("UnauthorizedException","403");//处理shiro的认证未通过异常
r.setExceptionMappings(mappings); // None by default
r.setDefaultErrorView("error"); // No default
r.setExceptionAttribute("ex"); // Default is "exception"
return r;
}
}
五、定义类继承AuthorizingRealm主要用来做登录验证和权限分配
public class MyShiroRelam extends AuthorizingRealm {
@Autowired
private IUserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
System.out.println("用户权限配置。。。。。。。。。。");
//访问@RequirePermission注解的url时触发
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
User userInfo = (User)principals.getPrimaryPrincipal();
//获得用户的角色,及权限进行绑定
for(Role role:userInfo.getRoleList()){
authorizationInfo.addRole(role.getRolename());
for(Permission p:role.getPermissions()){
authorizationInfo.addStringPermission(p.getPermission());
}
}
return authorizationInfo;
}
//验证用户登录信息
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("验证用户登录信息");
String username = (String)token.getPrincipal();
System.out.println("登录用户名: "+username);
System.out.println(token.getCredentials());
//从数据库查询出User信息及用户关联的角色,权限信息,以备权限分配时使用
User user = userService.findUserByName(username);
if(null == user) return null;
System.out.println("username: "+user.getUsername()+" ; password : "+user.getPassword());
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
user, //用户名
user.getPassword(), //密码
getName() //realm name
);
return authenticationInfo;
}
}
六、实体类
public class User {
private int id;
private String username;
private String password;
//用户的角色 一对多关系
private List<Role> roleList;
public int getId() {
return id;
}
public void setId(int 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 List<Role> getRoleList() {
return roleList;
}
public void setRoleList(List<Role> roleList) {
this.roleList = roleList;
}
}
public class Role {
private int id;
private String rolename;//角色名称
private String roledesc;//角色描述
private List<Permission> permissions;//角色权限关系 多对多 一个角色对应多个权限
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRolename() {
return rolename;
}
public void setRolename(String rolename) {
this.rolename = rolename;
}
public String getRoledesc() {
return roledesc;
}
public void setRoledesc(String roledesc) {
this.roledesc = roledesc;
}
public List<Permission> getPermissions() {
return permissions;
}
public void setPermissions(List<Permission> permissions) {
this.permissions = permissions;
}
}
public class Permission {
private int id;
private String modelname;
private String permission;
private List<Role> roles;//角色权限关系 多对多
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getModelname() {
return modelname;
}
public void setModelname(String modelname) {
this.modelname = modelname;
}
public String getPermission() {
return permission;
}
public void setPermission(String permission) {
this.permission = permission;
}
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
}
七、UserService接口编写
public interface IUserService {
public User findUserByName(String name);
}
@Service
public class UserServiceImpl implements IUserService {
@Autowired
private IUserDao userDao;
@Override
public User findUserByName(String name) {
return userDao.findUserByName(name);
}
}
八、UserDao接口编写
@Repository
@Mapper
public interface IUserDao {
public User findUserByName(String name);
}
UserDao.xml文件的编写
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="leonardo.ezio.permission.demo.shiro.dao.IUserDao">
<select id="findUserByName" parameterType="String" resultMap="user" >
select u.id u_id,username,password,r.id r_id ,rolename ,roledesc , p.id p_id ,modelname,permission from user u
INNER JOIN user_role ur on u.id = ur.uid
INNER JOIN role r ON ur.rid = r.id
INNER JOIN role_permission rp ON r.id = rp.rid
INNER JOIN permission p on rp.pid = p.id
where u.username = #{name}
</select>
<resultMap id="user" type="leonardo.ezio.permission.demo.shiro.bean.User">
<id property="id" column="u_id"></id>
<result property="username" column="username"/>
<result property="password" column="password"/>
<collection property="roleList" ofType="leonardo.ezio.permission.demo.shiro.bean.Role">
<id property="id" column="r_id"/>
<result property="rolename" column="rolename"/>
<result property="roledesc" column="roledesc"/>
<collection property="permissions" ofType="leonardo.ezio.permission.demo.shiro.bean.Permission">
<id property="id" column="p_id"/>
<result property="modelname" column="modelname"/>
<result property="permission" column="permission"/>
</collection>
</collection>
</resultMap>
</mapper>
九、Controller的编写
@Controller
public class HomeController {
@Autowired
private IUserService userService;
@RequestMapping({"/","/index"})
public String root(){
return "index";
}
@RequestMapping("/login")
public String login(HttpServletRequest request, Map<String ,String> map){
System.out.println("user login .....");
String exception = (String) request.getAttribute("shiroLoginFailure");
System.out.println("exception=" + exception);
String msg = "";
if (exception != null) {
if (UnknownAccountException.class.getName().equals(exception)) {
System.out.println("UnknownAccountException -- > 账号不存在:");
msg = "unknownAccount";
} else if (IncorrectCredentialsException.class.getName().equals(exception)) {
msg = "incorrectPassword";
} else if ("kaptchaValidateFailed".equals(exception)) {
System.out.println("kaptchaValidateFailed -- > 验证码错误");
msg = "kaptchaValidateFailed -- > 验证码错误";
} else {
msg = "else >> "+exception;
System.out.println("else -- >" + exception);
}
}
map.put("msg", msg);
//认证成功由shiro框架自行处理
return "login";
}
//访问此连接时会触发MyShiroRealm中的权限分配方法
@RequestMapping("/permission")
@RequiresPermissions("student:test")
public void test(){
System.out.println("permission test");
}
}
网友评论