shiro是开源安全框架,提供身份认证,授权,会话管理,加密等操作
会话管理:
传统项目是cookie维持会话管理,
前后分离开发是获取shiro的sessionId维持会话,参考:https://blog.csdn.net/u013615903/article/details/78781166/
本此整合默认用cookie管理,参考:https://www.cnblogs.com/asker009/p/9471712.html
1、项目结构
2、引入依赖,依赖涉及了JPA,mybatis、shiro、swagger等,做测试需要的依赖,贴上去
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.3.RELEASE
com.example
demo-1
0.0.1-SNAPSHOT
war
demo-1
Demo project for Spring Boot
1.8
1.2.37
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-logging
com.alibaba
druid-spring-boot-starter
1.1.10
org.springframework.session
spring-session-core
org.projectlombok
lombok
true
org.apache.shiro
shiro-spring
1.4.0
org.springframework.boot
spring-boot-starter-test
test
javax.servlet
javax.servlet-api
provided
org.springframework.boot
spring-boot-devtools
true
commons-httpclient
commons-httpclient
3.1
javax.servlet
jstl
org.springframework.boot
spring-boot-starter-tomcat
provided
org.springframework.boot
spring-boot-starter-data-redis
org.apache.tomcat.embed
tomcat-embed-jasper
provided
com.fasterxml.jackson.core
jackson-core
com.fasterxml.jackson.datatype
jackson-datatype-hibernate5
org.springframework.boot
spring-boot-starter-cache
net.sf.ehcache
ehcache
org.apache.commons
commons-lang3
commons-cli
commons-cli
1.2
commons-io
commons-io
2.2
com.alibaba
fastjson
${fastjson.version}
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.1.1
org.springframework.boot
spring-boot-starter-log4j2
com.spring4all
spring-boot-starter-swagger
1.5.0.RELEASE
mysql
mysql-connector-java
org.springframework.boot
spring-boot-maven-plugin
3、yml文件
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
platform: mysql
#url: jdbc:mysql://192.168.1.183:20001/dna?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSl=false
url: jdbc:mysql://127.0.0.1:3306/ly?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSl=false
username: root
password: 123456
initialSize: 10
minIdle: 10
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
filters: stat,wall,log4j2
logSlowSql: true
jpa:
hibernate:
ddl-auto: update
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl #按字段名字建表
show-sql: true
database: mysql
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
http:
encoding:
charset: utf-8
enabled: true
force: true
cache:
type: ehcache
ehcache:
config: classpath:ehcache.xml
redis:
host: 127.0.0.1
port: 6379
timeout: 20000
# 集群环境打开下面注释,单机不需要打开
# cluster:
# 集群信息
# nodes: xxx.xxx.xxx.xxx:xxxx,xxx.xxx.xxx.xxx:xxxx,xxx.xxx.xxx.xxx:xxxx
# #默认值是5 一般当此值设置过大时,容易报:Too many Cluster redirections
# maxRedirects: 3
pool:
max-active: 8
min-idle: 0
max-idle: 8
max-wait: -1
password:
jpa:
#按字段名字建表
#mybatis是独立节点,需要单独配置
mybatis:
typeAliasesPackage: com.example.ehcache.*
mapperLocations: classpath:mapper/*.xml
configuration:
map-underscore-to-camel-case: true
server:
port: 1234
session-timeout: 30
tomcat.max-threads: 0
tomcat.uri-encoding: UTF-8
servlet:
context-path: /test
logging:
config: classpath:log4j2-spring.xml
#redis集群
#热部署生效
#设置重启的目录
devtools:
restart:
enabled:true
additional-paths:src/main/java
4、配置自定义角色类
package com.example.demo.shiro.role;
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.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 org.springframework.beans.factory.annotation.Autowired;
import com.example.demo.shiro.entity.SysPermission;
import com.example.demo.shiro.entity.SysRole;
import com.example.demo.shiro.entity.Users;
import com.example.demo.shiro.service.UsersService;
import lombok.extern.log4j.Log4j2;
/**
*
* @desc shiro核心配置类
* @author luobw
*
* 2019年4月29日
*/
@Log4j2
public class MyShiroRealm extends AuthorizingRealm{
@Autowired
UsersService usersService;
//权限信息,包括角色以及权限
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
log.info("-----权限信息------->");
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
Users user = (Users) principals.getPrimaryPrincipal();
for (SysRole role : user.getRoleList()) {//获取角色
authorizationInfo.addRole(role.getRole());
for (SysPermission permission : role.getPermissions()) {//获取权限
authorizationInfo.addStringPermission(permission.getPermission());
}
}
return authorizationInfo;
}
/*主要是用来进行身份认证的,也就是说验证用户输入的账号和密码是否正确。*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
log.info("-----身份验证------->");
String userName = (String) token.getPrincipal();
log.info("---------->"+token.getCredentials());
Users users = usersService.findByUserName(userName);
log.info("-------->"+users);
if(users == null) {
return null;
}
//实际项目中,这里可以根据实际情况做缓存,如果不做,Shiro自己也是有时间间隔机制,2分钟内不会重复执行该方法
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo
(users, //这里传入的是user对象,比对的是用户名,直接传入用户名也没错,但是在授权部分就需要自己重新从数据库里取权限
users.getPassword(),
ByteSource.Util.bytes(users.getCredentialsSalt()),getName());
return simpleAuthenticationInfo;
}
}
5、配置shiro自定义加载类
package com.example.demo.shiro.config;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import com.example.demo.shiro.role.MyShiroRealm;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
/**
*
* @desc shiro配置
* @author luobw
*
* 2019年4月29日
*/
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
System.out.println("ShiroConfiguration.shirFilter()");
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
//拦截器.
Map filterChainDefinitionMap = new LinkedHashMap();
// 配置不会被拦截的链接 顺序判断,因为前端模板采用了thymeleaf,这里不能直接使用 ("/static/**", "anon")来配置匿名访问,必须配置到每个静态目录
filterChainDefinitionMap.put("/css/**", "anon");
filterChainDefinitionMap.put("/fonts/**", "anon");
filterChainDefinitionMap.put("/img/**", "anon");
filterChainDefinitionMap.put("/js/**", "anon");
filterChainDefinitionMap.put("/html/**", "anon");
//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/login", "anon");
//:这是一个坑呢,一不小心代码就不好使了;
//
filterChainDefinitionMap.put("/**", "authc");
// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
//传统项目中,登出后应重定向请求,到登录界面或其他指定界面,在前后端分离的项目中,我们应该返回json信息。在上面提到的ShiroConfig中配置了默认登录路由
shiroFilterFactoryBean.setLoginUrl("/unauth");
// 登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl("/index");
//未授权界面;
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
/**
* 凭证匹配器
* (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
* )
* @return
*/
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher(){
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;
hashedCredentialsMatcher.setHashIterations(2);//散列的次数,比如散列两次,相当于 md5(md5(""));
return hashedCredentialsMatcher;
}
@Bean
public MyShiroRealm myShiroRealm(){
MyShiroRealm myShiroRealm = new MyShiroRealm();
myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
return myShiroRealm;
}
@Bean
public SecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
return securityManager;
}
/**
* 开启shiro aop注解支持.
* 使用代理方式;所以需要开启代码支持;
* @param securityManager
* @return
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
@Bean(name="simpleMappingExceptionResolver")
public SimpleMappingExceptionResolver
createSimpleMappingExceptionResolver() {
SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver();
Properties mappings = new Properties();
mappings.setProperty("DatabaseException", "databaseError");//数据库异常处理
mappings.setProperty("UnauthorizedException","/user/403");
r.setExceptionMappings(mappings); // None by default
r.setDefaultErrorView("error"); // No default
r.setExceptionAttribute("exception"); // Default is "exception"
//r.setWarnLogCategory("example.MvcLogger"); // No default
return r;
}
}
6、涉及到的用户表、角色表、权限表
用户实体类
package com.example.demo.shiro.entity;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Id;
import org.hibernate.annotations.GenericGenerator;
import org.springframework.format.annotation.DateTimeFormat;
@Entity
@Table(name = "users")
public class Users {
@Id
@GenericGenerator(name="generator",strategy = "native")
@GeneratedValue(strategy= GenerationType.AUTO)
private Integer userId;
@Column(nullable = false, unique = true)
private String userName; //登录用户名
@Column(nullable = false)
private String name;//名称(昵称或者真实姓名,根据实际情况定义)
@Column(nullable = false)
private String password;
private String salt;//加密密码的盐
private byte state;//用户状态,0:创建未认证(比如没有激活,没有输入验证码等等)--等待验证的用户 , 1:正常状态,2:用户被锁定.
@ManyToMany(fetch= FetchType.EAGER)//立即从数据库中进行加载数据;
@JoinTable(name = "SysUserRole",
joinColumns = {
@JoinColumn(name = "userId")},
inverseJoinColumns ={
@JoinColumn(name = "roleId")})
private List roleList;// 一个用户具有多个角色
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
private LocalDateTime createTime;//创建时间
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate expiredDate;//过期日期
private String email;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public LocalDateTime getCreateTime() {
return createTime;
}
public void setCreateTime(LocalDateTime createTime) {
this.createTime = createTime;
}
public LocalDate getExpiredDate() {
return expiredDate;
}
public void setExpiredDate(LocalDate expiredDate) {
this.expiredDate = expiredDate;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
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 byte getState() {
return state;
}
public void setState(byte state) {
this.state = state;
}
public List getRoleList() {
return roleList;
}
public void setRoleList(List roleList) {
this.roleList = roleList;
}
/**
* 密码盐. 重新对盐重新进行了定义,用户名+salt,这样就不容易被破解,可以采用多种方式定义加盐
* @return
*/
public String getCredentialsSalt(){
return this.userName+this.salt;
}
}
角色实体类
package com.example.demo.shiro.entity;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Id;
import org.hibernate.annotations.GenericGenerator;
@Entity
@Table(name = "sysrole")
public class SysRole {
@Id
@GenericGenerator(name="generator",strategy = "native")
@GeneratedValue(strategy= GenerationType.AUTO)
private Integer roleId; // 编号
@Column(nullable = false, unique = true)
private String role; // 角色标识程序中判断使用,如"admin",这个是唯一的:
private String description; // 角色描述,UI界面显示使用
private Boolean available = Boolean.TRUE; // 是否可用,如果不可用将不会添加给用户
//角色 -- 权限关系:多对多关系;
@ManyToMany(fetch= FetchType.EAGER)
@JoinTable(name="SysRolePermission",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="permissionId")})
private List permissions;
// 用户 - 角色关系定义;
@ManyToMany
@JoinTable(name="SysUserRole",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="userId")})
private List users;// 一个角色对应多个用户
public Integer getRoleId() {
return roleId;
}
public void setRoleId(Integer roleId) {
this.roleId = roleId;
}
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;
}
public List getPermissions() {
return permissions;
}
public void setPermissions(List permissions) {
this.permissions = permissions;
}
public List getUsers() {
return users;
}
public void setUsers(List users) {
this.users = users;
}
}
权限实体类
package com.example.demo.shiro.entity;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Id;
import org.hibernate.annotations.GenericGenerator;
@Entity
@Table(name = "syspermission")
public class SysPermission {
@Id
@GenericGenerator(name="generator",strategy = "native")
@GeneratedValue(strategy= GenerationType.AUTO)
private Integer permissionId;//主键.
@Column(nullable = false)
private String permissionName;//名称.
@Column(columnDefinition="enum('menu','button')")
private String resourceType;//资源类型,[menu|button]
private String url;//资源路径.
private String permission; //权限字符串,menu例子:role:*,button例子:role:create,role:update,role:delete,role:view
private Long parentId; //父编号
private String parentIds; //父编号列表
private Boolean available = Boolean.TRUE;
//角色 -- 权限关系:多对多关系;
@ManyToMany
@JoinTable(name="SysRolePermission",joinColumns={@JoinColumn(name="permissionId")},inverseJoinColumns={@JoinColumn(name="roleId")})
private List roles;
public Integer getPermissionId() {
return permissionId;
}
public void setPermissionId(Integer permissionId) {
this.permissionId = permissionId;
}
public String getPermissionName() {
return permissionName;
}
public void setPermissionName(String permissionName) {
this.permissionName = permissionName;
}
public String getResourceType() {
return resourceType;
}
public void setResourceType(String resourceType) {
this.resourceType = resourceType;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getPermission() {
return permission;
}
public void setPermission(String permission) {
this.permission = permission;
}
public Long getParentId() {
return parentId;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
public String getParentIds() {
return parentIds;
}
public void setParentIds(String parentIds) {
this.parentIds = parentIds;
}
public Boolean getAvailable() {
return available;
}
public void setAvailable(Boolean available) {
this.available = available;
}
public List getRoles() {
return roles;
}
public void setRoles(List roles) {
this.roles = roles;
}
}
7、用户业务类,登录业务类
登录业务类
package com.example.demo.shiro.service;
import com.example.demo.shiro.entity.LoginResult;
public interface LoginService {
LoginResult login(String userName,String password);
void logout();
}
用户业务类
package com.example.demo.shiro.service;
import com.example.demo.shiro.entity.Users;
/**
*
* @desc
* @author luobw
*
* 2019年4月29日
*/
public interface UsersService {
Users findByUserName(String userName);
}
登录实现类
package com.example.demo.shiro.service.impl;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Service;
import com.example.demo.shiro.entity.LoginResult;
import com.example.demo.shiro.service.LoginService;
/**
*
* @desc 登录业务处理
* @author luobw
*
* 2019年4月29日
*/
@Service
public class LoginServiceImpl implements LoginService {
/**
* 登录
*/
@Override
public LoginResult login(String userName, String password) {
LoginResult loginResult = new LoginResult();
if(userName==null || userName.isEmpty()) {
loginResult.setLogin(false);
loginResult.setResult("用户名不能为空");
return loginResult;
}
String msg = "";
//获取subject实例对象
Subject subject = SecurityUtils.getSubject();
//将用户名和密码封装到UsernamePasswordToken
UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
//认证
try {
subject.login(token);
Session session = subject.getSession();
session.setAttribute("userName", userName);
loginResult.setLogin(true);
return loginResult;
} catch (UnknownAccountException e) {
e.printStackTrace();
msg = "UnknownAccountException -- > 账号不存在:";
} catch (IncorrectCredentialsException e) {
e.printStackTrace();
msg = "IncorrectCredentialsException -- > 密码不正确:";
}catch (AuthenticationException e) {
e.printStackTrace();
msg="用户验证失败";
}
loginResult.setLogin(true);
loginResult.setResult(msg);
return loginResult;
}
/**
* 退出
*/
@Override
public void logout() {
Subject subject = SecurityUtils.getSubject();
subject.logout();
}
}
用户实现类
package com.example.demo.shiro.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.demo.shiro.entity.Users;
import com.example.demo.shiro.repository.UserRepository;
import com.example.demo.shiro.service.UsersService;
@Service
public class ServiceImpl implements UsersService {
@Autowired
UserRepository userRepository;
@Override
public Users findByUserName(String userName) {
return userRepository.findByUserName(userName);
}
}
登录控制器类
package com.example.demo.shiro.controller;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.shiro.entity.LoginResult;
import com.example.demo.shiro.service.LoginService;
@RestController
public class MyLoginController {
@Resource
private LoginService loginService;
LoginResult loginResult = new LoginResult();
@RequestMapping({ "/", "/index" })
public String index() {
return "/index";
}
@RequestMapping("/403")
public LoginResult unauthorizedRole() {
System.out.println("------没有权限-------");
loginResult.setResult("没有权限");
return loginResult;
}
@RequestMapping(value = "/login", method = RequestMethod.POST)
public LoginResult login(Map map, HttpServletRequest request) throws Exception {
System.out.println("login()");
String userName = request.getParameter("userName");
String password = request.getParameter("password");
LoginResult loginResult = loginService.login(userName, password);
if (loginResult.isLogin()) {
return loginResult;
} else {
map.put("msg", loginResult.getResult());
map.put("userName", userName);
loginResult.setMap(map);
return loginResult;
}
}
@RequestMapping("/logout")
public LoginResult logOut(HttpSession session) {
loginService.logout();
loginResult.setResult("退出成功");
return loginResult;
}
/**
* 未登录,shiro应重定向到登录界面,此处返回未登录状态信息由前端控制跳转页面
*
* @return
*/
@RequestMapping(value = "/unauth")
public LoginResult unauth() {
Map map = new HashMap();
map.put("code", "1000000");
map.put("msg", "未登录");
loginResult.setMap(map);
return loginResult;
}
@RequestMapping(value = "/auth")
public LoginResult auth() {
Map map = new HashMap();
map.put("code", "200");
map.put("msg", "登录");
loginResult.setMap(map);
return loginResult;
}
@RequestMapping(value = "/user/403")
public LoginResult exce() {
Map map = new HashMap();
map.put("code", "500");
map.put("msg", "数据异常");
loginResult.setMap(map);
return loginResult;
}
/*
@RequestMapping(value = "/error")
public LoginResult error() {
Map map = new HashMap();
map.put("code", "500");
map.put("msg", "error异常");
loginResult.setMap(map);
return loginResult;
}*/
}
用户控制器类
package com.example.demo.shiro.controller;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.shiro.entity.LoginResult;
@RestController
@RequestMapping("/user")
public class UserController {
LoginResult loginResult = new LoginResult();
/**
* 用户查询.
* @return
*/
@RequestMapping(value = "/userList",method=RequestMethod.GET)
@RequiresPermissions("user:view")//权限管理;
public LoginResult userInfo(){
loginResult.setLogin(true);
loginResult.setResult("用户查询");
return loginResult;
}
/**
* 用户添加;
* @return
*/
@RequestMapping("/userAdd")
@RequiresPermissions("user:add")//权限管理;
public LoginResult userInfoAdd(){
loginResult.setLogin(true);
loginResult.setResult("用户添加");
return loginResult;
}
/**
* 用户删除;
* @return
*/
@RequestMapping("/userDel")
@RequiresPermissions("user:del")//权限管理;
public LoginResult userDel(){
loginResult.setLogin(true);
loginResult.setResult("用户删除");
return loginResult;
}
}
返回值类
package com.example.demo.shiro.entity;
import java.util.Map;
public class LoginResult {
private boolean isLogin = false;
private String result;
private Map map;
public Map getMap() {
return map;
}
public void setMap(Map map) {
this.map = map;
}
public boolean isLogin() {
return isLogin;
}
public void setLogin(boolean login) {
isLogin = login;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
}
启动项目自动创建表结构,需导入sql数据
INSERT INTO `users` (`userId`,`username`,`name`,`password`,`salt`,`state`)
VALUES ('1', 'admin', '管理员', 'd3c59d25033dbf980d29554025c23a75', '8d78869f470951332959580424d4bf4f', 0);
INSERT INTO `syspermission` (`permissionId`,`available`,`permissionname`,`parentid`,`parentids`,`permission`,`resourcetype`,`url`)
VALUES (1,0,'用户管理',0,'0/','user:view','menu','user/userList');
INSERT INTO `syspermission` (`permissionId`,`available`,`permissionname`,`parentid`,`parentids`,`permission`,`resourcetype`,`url`)
VALUES (2,0,'用户添加',1,'0/1','user:add','button','user/userAdd');
INSERT INTO `syspermission` (`permissionId`,`available`,`permissionname`,`parentid`,`parentids`,`permission`,`resourcetype`,`url`)
VALUES (3,0,'用户删除',1,'0/1','user:del','button','user/userDel');
INSERT INTO `sysrole` (`roleid`,`available`,`description`,`role`) VALUES (1,0,'管理员','admin');
INSERT INTO `sysrole` (`roleid`,`available`,`description`,`role`) VALUES (2,0,'VIP会员','vip');
INSERT INTO `sysrole` (`roleid`,`available`,`description`,`role`) VALUES (3,1,'test','test');
INSERT INTO `sysrolepermission` (`permissionid`,`roleid`) VALUES (1,1);
INSERT INTO `sysrolepermission` (`permissionid`,`roleid`) VALUES (2,1);
INSERT INTO `sysrolepermission` (`permissionid`,`roleid`) VALUES (3,2);
INSERT INTO `sysuserrole` (`roleid`,`userId`) VALUES (1,1);
7、运行调试
1.未登录访问用户列表
get 192.168.1.63:1234/test/user/userList
2、登录请求
post 192.168.1.63:1234/test/login?userName=admin&password=123456
3、再次访问用户列表
4、退出请求
get 192.168.1.63:1234/test/logout