本文共 16749 字,大约阅读时间需要 55 分钟。
写代码前可以简单了解一下 Shiro
4.0.0 org.springframework.boot spring-boot-starter-parent 1.5.16.RELEASE org.example shiro 1.0-SNAPSHOT war shiro Demo project for shiro 1.8 org.projectlombok lombok 1.18.12 org.mybatis.spring.boot mybatis-spring-boot-starter 1.3.1 org.springframework.boot spring-boot-starter-web mysql mysql-connector-java runtime org.springframework.boot spring-boot-starter-tomcat provided org.apache.shiro shiro-core 1.3.2 org.apache.shiro shiro-spring 1.3.2 com.alibaba druid 1.0.20 org.apache.commons commons-lang3 3.4 org.springframework spring-context-support 4.2.3.RELEASE org.apache.tomcat.embed tomcat-embed-jasper javax.servlet javax.servlet-api javax.servlet jstl org.springframework.boot spring-boot-maven-plugin
# 数据库配置spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF-8 username: root password: 123456 # jsp 配置 前缀/后缀 mvc: view: prefix: /pages/ suffix: .jsp# mybatis 配置mybatis: mapper-locations: mappers/*.xml type-aliases-package: org.main.entity
创建与数据库对应的实体类,主要有 User、Role、Permission 这三个实体类,代码如下:
package org.main.entity;import lombok.Data;import java.io.Serializable;/** * 角色权限类 * @Author: bai * @DateTime: 2020/6/25 9:21 */@Datapublic class Permission implements Serializable { /** * 权限id */ private Integer pid; /** * 权限组名称 */ private String name; /** * 可访问的 url */ private String url;}
package org.main.entity;import lombok.Data;import java.io.Serializable;import java.util.HashSet;import java.util.Set;/** * 角色类 * @Author: bai * @DateTime: 2020/6/25 9:22 */@Datapublic class Role implements Serializable { /** * 角色id */ private Integer rid; /** * 角色名称 */ private String rname; /** * 角色权限[单角色可能具备多种权限] */ private Setpermissions = new HashSet (); /** * 角色属于哪个用户[单角色可能属于多个用户],[同时有多人具备同一种角色] */ private Set users = new HashSet ();}
package org.main.entity;import lombok.Data;import java.io.Serializable;import java.util.HashSet;import java.util.Set;/** * 用户类 * @Author: bai * @DateTime: 2020/6/25 9:23 */@Datapublic class User implements Serializable { /** * 用户id */ private Integer uid; /** * 用户名 */ private String username; /** * 密码 */ private String password; /** * 用户的角色[单用户可能具备多种角色] */ private Setroles = new HashSet ();}
package org.main.mapper;import org.apache.ibatis.annotations.Param;import org.main.entity.User;/** * @Author: bai * @DateTime: 2020/6/25 9:29 */public interface UserMapper { User findByUsername(@Param("username") String username);}
package org.main;import org.mybatis.spring.annotation.MapperScan;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.ComponentScan;/** * @Author: bai * @DateTime: 2020/6/25 9:30 */@SpringBootApplication@ComponentScan@MapperScan(basePackages = { "org.main.mapper"})public class ShrioApplication { public static void main(String[] args) { SpringApplication.run(ShrioApplication.class, args); }}
-- 权限表--CREATE TABLE permission ( pid int(11) NOT NULL AUTO_INCREMENT, name VARCHAR(255) NOT NULL DEFAULT '', url VARCHAR(255) DEFAULT '', PRIMARY KEY (pid)) ENGINE =InnoDB DEFAULT CHARSET = utf8;INSERT INTO permission VALUES ('1','add','');INSERT INTO permission VALUES ('2','delete','');INSERT INTO permission VALUES ('3','edit','');INSERT INTO permission VALUES ('4','query','');-- 用户表--CREATE TABLE user(uid int(11) NOT NULL AUTO_INCREMENT,username VARCHAR(255) NOT NULL DEFAULT '',password VARCHAR(255) NOT NULL DEFAULT '',PRIMARY KEY (uid)) ENGINE =InnoDB DEFAULT CHARSET=utf8;INSERT INTO user VALUES ('1','admin','123');INSERT INTO user VALUES ('2','demo','123');-- 角色表--CREATE TABLE role(rid int(11) NOT NULL AUTO_INCREMENT,rname VARCHAR(255) NOT NULL DEFAULT '',PRIMARY KEY (rid)) ENGINE =InnoDB DEFAULT CHARSET=utf8;INSERT INTO role VALUES ('1','admin');INSERT INTO role VALUES ('2','customer');-- 权限角色关系表--CREATE TABLE permission_role( rid int(11) NOT NULL , pid int(11) NOT NULL , KEY idx_rid(rid), KEY idx_pid(pid)) ENGINE = InnoDB DEFAULT CHARSET = utf8;INSERT INTO permission_role VALUES ('1','1');INSERT INTO permission_role VALUES ('1','2');INSERT INTO permission_role VALUES ('1','3');INSERT INTO permission_role VALUES ('1','4');INSERT INTO permission_role VALUES ('2','1');INSERT INTO permission_role VALUES ('2','4');-- 用户角色关系表--CREATE TABLE user_role( uid int(11) NOT NULL , rid int(11) NOT NULL , KEY idx_uid(uid), KEY idx_rid(rid)) ENGINE = InnoDB DEFAULT CHARSET = utf8;INSERT INTO user_role VALUES (1,1);INSERT INTO user_role VALUES (2,2);
package org.main.config;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.main.entity.Permission;import org.main.entity.Role;import org.main.entity.User;import org.main.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.apache.commons.collections.CollectionUtils;import java.util.ArrayList;import java.util.List;import java.util.Set;/** * @Author: bai * @DateTime: 2020/6/25 9:41 */public class AuthRealm extends AuthorizingRealm { @Autowired private UserService userService; //授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { User user = (User) principals.fromRealm(this.getClass().getName()).iterator().next(); ListpermissionList = new ArrayList (); List roleNameList = new ArrayList (); Set roleSet = user.getRoles(); if (CollectionUtils.isNotEmpty(roleSet)) { for (Role role : roleSet) { roleNameList.add(role.getRname()); Set permissionSet = role.getPermissions(); if (CollectionUtils.isNotEmpty(permissionSet)) { for (Permission permission : permissionSet) { permissionList.add(permission.getName()); } } } } SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.addStringPermissions(permissionList); info.addRoles(roleNameList); return info; } // 认证登陆 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) authenticationToken; String username = usernamePasswordToken.getUsername(); User user = userService.findByUsername(username); return new SimpleAuthenticationInfo(user, user.getPassword(), this.getClass().getName()); }}
package org.main.config;import org.apache.shiro.cache.MemoryConstrainedCacheManager;import org.apache.shiro.mgt.SecurityManager;import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;import org.apache.shiro.web.mgt.DefaultWebSecurityManager;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: bai * @DateTime: 2020/6/25 9:52 */@Configurationpublic class ShiroConfiguration { @Bean("shiroFilter") public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager manager) { ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); bean.setSecurityManager(manager); bean.setLoginUrl("/login"); bean.setSuccessUrl("/index"); bean.setUnauthorizedUrl("/unauthorized"); LinkedHashMapfilterChainDefinitionMap = new LinkedHashMap (); // authc 表示只有登陆后才有权限访问,anon 表示没有登陆也有权限访问 filterChainDefinitionMap.put("/index", "authc"); filterChainDefinitionMap.put("/login", "anon"); filterChainDefinitionMap.put("/loginUser", "anon"); // admin 接口指允许admin角色访问 filterChainDefinitionMap.put("/admin", "roles[admin]"); filterChainDefinitionMap.put("/edit", "perms[edit]"); // 开放druid所有请求,可以访问druid监控 filterChainDefinitionMap.put("/**", "user"); bean.setFilterChainDefinitionMap(filterChainDefinitionMap); return bean; } @Bean("securityManager") public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm) { DefaultWebSecurityManager manager = new DefaultWebSecurityManager(); manager.setRealm(authRealm); return manager; } @Bean("authRealm") public AuthRealm authRealm(@Qualifier("credentialMatcher") CredentialMatcher credentialMatcher) { AuthRealm authRealm = new AuthRealm(); // 使用缓存 authRealm.setCacheManager(new MemoryConstrainedCacheManager()); authRealm.setCredentialsMatcher(credentialMatcher); return authRealm; } @Bean("credentialMatcher") public CredentialMatcher credentialMatcher() { return new CredentialMatcher(); } /** * 以下的两个方法是设置 shiro 与 spring 之间的关联 * * @param securityManager * @return */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); advisor.setSecurityManager(securityManager); return advisor; } @Bean public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator(); creator.setProxyTargetClass(true); return creator; }}
package org.main.config;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;/** * 密码校验规则 * * @Author: bai * @DateTime: 2020/6/25 10:03 */public class CredentialMatcher extends SimpleCredentialsMatcher { @Override public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token; String password = new String(usernamePasswordToken.getPassword()); String dbPassword = (String) info.getCredentials(); return this.equals(password, dbPassword); }}
package org.main.service;import org.main.entity.User;import org.main.mapper.UserMapper;import org.springframework.stereotype.Service;import javax.annotation.Resource;/** * @Author: bai * @DateTime: 2020/6/25 9:42 */@Servicepublic class UserService { @Resource private UserMapper userMapper; public User findByUsername(String username) { return userMapper.findByUsername(username); }}
package org.main.controller;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.subject.Subject;import org.main.entity.User;import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpSession;/** * @Author: bai * @DateTime: 2020/6/25 10:10 */@RestControllerpublic class UserController { @GetMapping(value = "/login") public String login() { return "login"; } /** * 两个case * 第一个是只有登陆后才能访问相关的接口,没有登陆是不允许访问相关的接口,例如admin接口 * 第二个是某些接口只能被某些角色访问 * @return */ @GetMapping(value = "/admin") public String admin() { return "admin success"; } @GetMapping(value = "/logout") public String logout() { Subject subject = SecurityUtils.getSubject(); if (null != subject) { subject.logout(); } return "login"; } @GetMapping(value = "/index") public String index() { return "index"; } @GetMapping(value = "/edit") public String edit() { return "edit success"; } @GetMapping(value = "/unauthorized") public String unauthorized() { return "unauthorized"; } @PostMapping(value = "/loginUser") public String loginUser(@RequestParam(value = "username") String username, @RequestParam(value = "password") String password, HttpSession session) { UsernamePasswordToken token = new UsernamePasswordToken(username, password); Subject subject = SecurityUtils.getSubject(); try { subject.login(token); User user = (User) subject.getPrincipal(); session.setAttribute("user", user); return "index"; } catch (Exception e) { e.printStackTrace(); return "login"; } }}
index.jsp
<%-- Created by IntelliJ IDEA. User: bai Date: 2020/6/25 Time: 10:20 To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %>Home 欢迎登陆, ${user.username}
login.jsp
<%-- Created by IntelliJ IDEA. User: bai Date: 2020/6/25 Time: 10:21 To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %>Login 欢迎登陆
unauthorized.jsp
<%-- Created by IntelliJ IDEA. User: bai Date: 2020/6/25 Time: 10:22 To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %>Unauthorized Unauthorized!
转载地址:http://ovqwi.baihongyu.com/