Shiro是一个非常不错的权限框架,它提供了登录和权限验证功能,如果想去了解它的话可以去Shiro官网学习 点击打开
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for module
-- ----------------------------
DROP TABLE IF EXISTS `module`;
CREATE TABLE `module` (
`mid` int(11) NOT NULL AUTO_INCREMENT,
`mname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`mid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of module
-- ----------------------------
INSERT INTO `module` VALUES (1, 'add');
INSERT INTO `module` VALUES (2, 'delete');
INSERT INTO `module` VALUES (3, 'query');
INSERT INTO `module` VALUES (4, 'update');
-- ----------------------------
-- Table structure for module_role
-- ----------------------------
DROP TABLE IF EXISTS `module_role`;
CREATE TABLE `module_role` (
`rid` int(11) NULL DEFAULT NULL,
`mid` int(11) NULL DEFAULT NULL,
INDEX `rid`(`rid`) USING BTREE,
INDEX `mid`(`mid`) USING BTREE,
CONSTRAINT `mid` FOREIGN KEY (`mid`) REFERENCES `module` (`mid`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `rid` FOREIGN KEY (`rid`) REFERENCES `role` (`rid`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of module_role
-- ----------------------------
INSERT INTO `module_role` VALUES (1, 1);
INSERT INTO `module_role` VALUES (1, 2);
INSERT INTO `module_role` VALUES (1, 3);
INSERT INTO `module_role` VALUES (1, 4);
INSERT INTO `module_role` VALUES (2, 1);
INSERT INTO `module_role` VALUES (2, 3);
-- ----------------------------
-- Table structure for role
-- ----------------------------
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
`rid` int(11) NOT NULL AUTO_INCREMENT,
`rname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`rid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of role
-- ----------------------------
INSERT INTO `role` VALUES (1, 'admin');
INSERT INTO `role` VALUES (2, 'customer');
INSERT INTO `role` VALUES (3, NULL);
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`uid` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`uid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, 'hlhdidi', '123');
INSERT INTO `user` VALUES (2, 'xyycici', '1992');
INSERT INTO `user` VALUES (3, 'sujin', '123');
-- ----------------------------
-- Table structure for user_role
-- ----------------------------
DROP TABLE IF EXISTS `user_role`;
CREATE TABLE `user_role` (
`uid` int(11) NULL DEFAULT NULL,
`rid` int(11) NULL DEFAULT NULL,
INDEX `u_fk`(`uid`) USING BTREE,
INDEX `r_fk`(`rid`) USING BTREE,
CONSTRAINT `r_fk` FOREIGN KEY (`rid`) REFERENCES `role` (`rid`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `u_fk` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of user_role
-- ----------------------------
INSERT INTO `user_role` VALUES (1, 1);
INSERT INTO `user_role` VALUES (2, 2);
INSERT INTO `user_role` VALUES (3, 3);
SET FOREIGN_KEY_CHECKS = 1;
当新添加一个用户时,只需要配置权限即可,module_role表中已经配置了什么权限拥有什么样的功能
SELECT u.*,r.*,m.* FROM user u inner join user_role ur on ur.uid=u.uid
inner join role r on r.rid=ur.rid
inner join module_role mr on mr.rid=r.rid
inner join module m on mr.mid=m.mid
WHERE username='hlhdidi'; -- xyycici用户已分配只要两个权限 add和query
org.apache.shiro
shiro-spring
1.2.5
org.apache.shiro
shiro-ehcache
1.2.5
com.github.theborakompanioni
thymeleaf-extras-shiro
1.2.1
仅列出关键实体类,其他实体类无需改动
package com.king.s5.model;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
//用户
public class User implements Serializable{
private Integer uid;
private String username;
private String password;
private Set roles = new HashSet<>();
public User(Integer uid, String username, String password) {
this.uid = uid;
this.username = username;
this.password = password;
}
public User() {
super();
}
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
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 Set getRoles() {
return roles;
}
public void setRoles(Set roles) {
this.roles = roles;
}
}
package com.king.s5.model;
import java.util.HashSet;
import java.util.Set;
//功能
public class Module {
private Integer mid;
private String mname;
private Set roles;
public Module(Integer mid, String mname) {
this.mid = mid;
this.mname = mname;
}
public Module() {
super();
}
public Integer getMid() {
return mid;
}
public void setMid(Integer mid) {
this.mid = mid;
}
public String getMname() {
return mname;
}
public void setMname(String mname) {
this.mname = mname;
}
public Set getRoles() {
return roles;
}
public void setRoles(Set roles) {
this.roles = roles;
}
}
public class Role {
private Integer rid;
private String rname;
private Set users = new HashSet<>();
private Set Modules = new HashSet<>();
public Role(Integer rid, String rname) {
this.rid = rid;
this.rname = rname;
}
public Role() {
super();
}
public Integer getRid() {
return rid;
}
public void setRid(Integer rid) {
this.rid = rid;
}
public String getRname() {
return rname;
}
public void setRname(String rname) {
this.rname = rname;
}
public Set getUsers() {
return users;
}
public void setUsers(Set users) {
this.users = users;
}
public Set getModules() {
return Modules;
}
public void setModules(Set modules) {
Modules = modules;
}
}
userMapper.xml,本次只写到mapper层,不做service层(仅列出关键mapper.xml),其他xml无需改变
uid, username, password
delete from user
where uid = #{uid,jdbcType=INTEGER}
insert into user (uid, username, password
)
values (#{uid,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}
)
insert into user
uid,
username,
password,
#{uid,jdbcType=INTEGER},
#{username,jdbcType=VARCHAR},
#{password,jdbcType=VARCHAR},
update user
username = #{username,jdbcType=VARCHAR},
password = #{password,jdbcType=VARCHAR},
where uid = #{uid,jdbcType=INTEGER}
update user
set username = #{username,jdbcType=VARCHAR},
password = #{password,jdbcType=VARCHAR}
where uid = #{uid,jdbcType=INTEGER}
mid, mname
delete from module
where mid = #{mid,jdbcType=INTEGER}
insert into module (mid, mname)
values (#{mid,jdbcType=INTEGER}, #{mname,jdbcType=VARCHAR})
insert into module
mid,
mname,
#{mid,jdbcType=INTEGER},
#{mname,jdbcType=VARCHAR},
update module
mname = #{mname,jdbcType=VARCHAR},
where mid = #{mid,jdbcType=INTEGER}
update module
set mname = #{mname,jdbcType=VARCHAR}
where mid = #{mid,jdbcType=INTEGER}
package com.king.s5.shiro;
import com.king.s5.biz.IUserBiz;
import com.king.s5.mapper.UserMapper;
import com.king.s5.model.Module;
import com.king.s5.model.Role;
import com.king.s5.model.User;
import org.apache.shiro.authc.*;
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.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class AuthRealm extends AuthorizingRealm {
@Autowired
private UserMapper userMapper;
//认证.登录
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken utoken=(UsernamePasswordToken) token;//获取用户输入的token
String username = utoken.getUsername();
User user = userMapper.queryUserName(username);
//放入shiro.调用CredentialsMatcher检验密码
return new SimpleAuthenticationInfo(user, user.getPassword(),this.getClass().getName());
}
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
//获取session中的用户
User user=(User) principal.fromRealm(this.getClass().getName()).iterator().next();
List permissions=new ArrayList<>();
Set roles = user.getRoles();
if(roles.size()>0) {
for(Role role : roles) {
Set modules = role.getModules();
if(modules.size()>0) {
for(Module module : modules) {
permissions.add(module.getMname());
}
}
}
}
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
//将权限放入shiro中.
info.addStringPermissions(permissions);
return info;
}
}
package com.king.s5.shiro;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
public class CredentialsMatcher extends SimpleCredentialsMatcher {
//校验
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
UsernamePasswordToken utoken=(UsernamePasswordToken) token;
//获得用户输入的密码:(可以采用加盐(salt)的方式去检验)
String inPassword = new String(utoken.getPassword());
//获得数据库中的密码
String dbPassword=(String) info.getCredentials();
//进行密码的比对
return this.equals(inPassword, dbPassword);
}
}
package com.king.s5.shiro;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.LinkedHashMap;
/**
* shiro的配置类
* @author sujin
*
*/
@Configuration
public class ShiroConfiguration {
@Bean(name="shiroFilter")
public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager manager) {
ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean();
bean.setSecurityManager(manager);
//配置登录的url和登录成功的url
bean.setLoginUrl("/login");
bean.setSuccessUrl("/home");
//配置访问权限
LinkedHashMap filterChainDefinitionMap=new LinkedHashMap<>();
filterChainDefinitionMap.put("/login*", "anon"); //表示可以匿名访问
filterChainDefinitionMap.put("/loginUser", "anon");
filterChainDefinitionMap.put("/client/test", "anon");
filterChainDefinitionMap.put("/assert/test", "anon");//添加白名单
filterChainDefinitionMap.put("/assert/get", "anon");//添加白名单
filterChainDefinitionMap.put("/assert/assertQuery", "anon");//添加白名单
filterChainDefinitionMap.put("/a", "anon");
filterChainDefinitionMap.put("/book/list", "anon");
filterChainDefinitionMap.put("/logout*","anon");
filterChainDefinitionMap.put("/jsp/error.jsp*","anon");
filterChainDefinitionMap.put("/jsp/login.jsp*","authc");
filterChainDefinitionMap.put("/*", "authc");//表示需要认证才可以访问
filterChainDefinitionMap.put("/**", "authc");//表示需要认证才可以访问
filterChainDefinitionMap.put("/*.*", "authc");
bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return bean;
}
//配置核心安全事务管理器
@Bean(name="securityManager")
public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm) {
System.err.println("--------------shiro已经加载----------------");
DefaultWebSecurityManager manager=new DefaultWebSecurityManager();
manager.setRealm(authRealm);
return manager;
}
//配置自定义的权限登录器
@Bean(name="authRealm")
public AuthRealm authRealm(@Qualifier("credentialsMatcher") CredentialsMatcher matcher) {
AuthRealm authRealm=new AuthRealm();
authRealm.setCredentialsMatcher(matcher);
return authRealm;
}
//配置自定义的密码比较器
@Bean(name="credentialsMatcher")
public CredentialsMatcher credentialsMatcher() {
return new CredentialsMatcher();
}
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
return new LifecycleBeanPostProcessor();
}
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
DefaultAdvisorAutoProxyCreator creator=new DefaultAdvisorAutoProxyCreator();
creator.setProxyTargetClass(true);
return creator;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager manager) {
AuthorizationAttributeSourceAdvisor advisor=new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(manager);
return advisor;
}
}
package com.king.s5.controller;
import com.king.s5.model.User;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpSession;
@Controller
public class LoginController {
@RequestMapping("/login")
public String login() {
return "login";
}
@RequestMapping("/a")
public String a() {
return "a";
}
@RequestMapping("/loginUser")
public String loginUser(String username,String password,HttpSession session) {
//授权认证
UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken(username,password);
Subject subject = SecurityUtils.getSubject();
try {
//完成登录
subject.login(usernamePasswordToken);
//获得用户对象
User user=(User) subject.getPrincipal();
//存入session
session.setAttribute("user", user);
return "index";
} catch(Exception e) {
return "login";//返回登录页面
}
}
@RequestMapping("/logOut")
public String logOut(HttpSession session) {
Subject subject = SecurityUtils.getSubject();
subject.logout();
// session.removeAttribute("user");
return "login";
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
登录
欢迎登录!${user.username }