Springboot项目搭建(3)-shiro登录
参考:https://www.jianshu.com/p/7f724bec3dc3
(1)添加依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
(2)添加用户实体类
package com.songyan.share.model; import java.util.Set; /**
* @author songyan
* @date 2020年3月19日
* @desc: 用户
*/
public class User {
private String userName;
private String id;
private String password;
private String name;
private Set<Role> roles; public User() {
} public User(String id, String userName, String password, Set<Role> roles) {
this.id = id;
this.userName = userName;
this.password = password;
this.roles = roles;
} public Set<Role> getRoles() {
return roles;
} public void setRoles(Set<Role> roles) {
this.roles = roles;
} public Set<Role> getRoleSet() {
return roles;
} public void setRoleSet(Set<Role> roles) {
this.roles = roles;
} public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
} }
(3)添加角色实体类
package com.songyan.share.model; import java.util.Set; /**
* @author songyan
* @date 2020年3月19日
* @desc: 角色类
*/
public class Role {
private String id;
private String roleName;
private Set<Permissions> permissions; public Role(String id, String roleName, Set<Permissions> permissions) {
this.id = id;
this.roleName = roleName;
this.permissions = permissions;
} public Role() {
} public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getRoleName() {
return roleName;
} public void setRoleName(String roleName) {
this.roleName = roleName;
} public Set<Permissions> getPermissions() {
return permissions;
} public void setPermissions(Set<Permissions> permissions) {
this.permissions = permissions;
} }
(4)添加权限实体类
package com.songyan.share.model; /**
* @author songyan
* @date 2020年3月19日
* @desc: 权限类
*/
public class Permissions {
private String id;
private String permissionsName;
public Permissions() {
}
public Permissions(String id, String permissionsName) {
this.id = id;
this.permissionsName = permissionsName;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPermissionsName() {
return permissionsName;
}
public void setPermissionsName(String permissionsName) {
this.permissionsName = permissionsName;
} }
(5)添加登录的service层
package com.songyan.share.service; import com.songyan.share.model.User; /**
* @author songyan
* @date 2020年3月19日
* @desc:
*/
public interface LoginService { User getUserByName(String getMapByName);
}
package com.songyan.share.service.impl; import org.springframework.stereotype.Service; import com.songyan.share.model.Permissions;
import com.songyan.share.model.Role;
import com.songyan.share.model.User;
import com.songyan.share.service.LoginService; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* @author songyan
* @date 2020年3月19日
* @desc:
*/
@Service
public class LoginServiceImpl implements LoginService { @Override
public User getUserByName(String getMapByName) {
//模拟数据库查询,正常情况此处是从数据库或者缓存查询。
return getMapByName(getMapByName);
} /**
* 模拟数据库查询
* @param userName
* @return
*/
private User getMapByName(String userName){
//共添加两个用户,两个用户都是admin一个角色,
//wsl有query和add权限,zhangsan只有一个query权限
Permissions permissions1 = new Permissions("1","query");
Permissions permissions2 = new Permissions("2","add");
Set<Permissions> permissionsSet = new HashSet<>();
permissionsSet.add(permissions1);
permissionsSet.add(permissions2);
Role role = new Role("1","admin",permissionsSet);
Set<Role> roleSet = new HashSet<>();
roleSet.add(role);
User user = new User("1","wsl","123456",roleSet);
Map<String ,User> map = new HashMap<>();
map.put(user.getUserName(), user); Permissions permissions3 = new Permissions("3","query");
Set<Permissions> permissionsSet1 = new HashSet<>();
permissionsSet1.add(permissions3);
Role role1 = new Role("2","user",permissionsSet1);
Set<Role> roleSet1 = new HashSet<>();
roleSet1.add(role1);
User user1 = new User("2","zhangsan","123456",roleSet1);
map.put(user1.getUserName(), user1);
return map.get(userName);
}
}
(6)自定义Realm用于查询用户的角色和权限信息并保存到权限管理器:
package com.songyan.share.shiro; import com.songyan.share.model.Permissions;
import com.songyan.share.model.Role;
import com.songyan.share.model.User;
import com.songyan.share.service.LoginService;
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.springframework.beans.factory.annotation.Autowired; /**
* @author songyan
* @date 2020年3月19日
* @desc:
*/
public class CustomRealm extends AuthorizingRealm { @Autowired
private LoginService loginService; @Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//获取登录用户名
String name = (String) principalCollection.getPrimaryPrincipal();
//根据用户名去数据库查询用户信息
User user = loginService.getUserByName(name);
//添加角色和权限
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
for (Role role : user.getRoles()) {
//添加角色
simpleAuthorizationInfo.addRole(role.getRoleName());
//添加权限
for (Permissions permissions : role.getPermissions()) {
simpleAuthorizationInfo.addStringPermission(permissions.getPermissionsName());
}
}
return simpleAuthorizationInfo;
} @Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//加这一步的目的是在Post请求的时候会先进认证,然后在到请求
if (authenticationToken.getPrincipal() == null) {
return null;
}
//获取用户信息
String name = authenticationToken.getPrincipal().toString();
User user = loginService.getUserByName(name);
if (user == null) {
//这里返回后会报出对应异常
return null;
} else {
//这里验证authenticationToken和simpleAuthenticationInfo的信息
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, user.getPassword().toString(), getName());
return simpleAuthenticationInfo;
}
}
}
(7)把CustomRealm和SecurityManager等加入到spring容器:
package com.songyan.share.shiro; 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.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import java.util.LinkedHashMap;
import java.util.Map; import javax.servlet.Filter; /**
* @author songyan
* @date 2020年3月19日
* @desc:
*/
@Configuration
public class ShiroConfig {
//不加这个注解不生效,具体不详
@Bean
@ConditionalOnMissingBean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
defaultAAP.setProxyTargetClass(true);
return defaultAAP;
} //将自己的验证方式加入容器
@Bean
public CustomRealm myShiroRealm() {
CustomRealm customRealm = new CustomRealm();
return customRealm;
} //权限管理,配置主要是Realm的管理认证
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
return securityManager;
} @Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(org.apache.shiro.mgt.SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);//安全管理器
Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
filterChainDefinitionMap.put("/login", "anon");//配置自定义过滤器**
filterChainDefinitionMap.put("/favicon.ico", "anon");
filterChainDefinitionMap.put("/css/**", "anon");//静态文件目录
filterChainDefinitionMap.put("/img/**", "anon");//静态文件目录
filterChainDefinitionMap.put("/js/**", "anon");//静态文件目录
filterChainDefinitionMap.put("/plugin/**", "anon");//静态文件目录
filterChainDefinitionMap.put("/error/**", "anon");
filterChainDefinitionMap.put("/doLogin/**", "anon");
filterChainDefinitionMap.put("/logout", "logout");//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setLoginUrl("/login");// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
shiroFilterFactoryBean.setSuccessUrl("/");// 登录成功后要跳转的链接
shiroFilterFactoryBean.setUnauthorizedUrl("/error/403.html");//未授权界面
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);//路径拦截器.
return shiroFilterFactoryBean;
} //加入注解的使用,不加入这个注解不生效
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
}
(8)登录控制器
package com.songyan.share.controller; import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import com.songyan.share.model.ReturnCode;
import com.songyan.share.model.ReturnObj;
import com.songyan.share.model.User; /**
* @author songyan
* @date 2020年3月19日
* @desc: 登录
*/
@RestController
public class LoginController { @RequestMapping("/doLogin")
public Object doLogin(@RequestBody User user) {
//添加用户认证信息
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(
user.getUserName(),
user.getPassword()
);
try {
//进行验证,这里可以捕获异常,然后返回对应信息
subject.login(usernamePasswordToken);
// subject.checkRole("admin");
// subject.checkPermissions("query", "add");
} catch (AuthenticationException e) {
e.printStackTrace();
return new ReturnObj("账号或密码错误!",ReturnCode.ERROR_CODE);
}
return new ReturnObj("登录成功");
}
//注解验角色和权限
@RequiresRoles("admin")
@RequiresPermissions("add")
@RequestMapping("/index")
public String index() {
return "index!";
}
}
问题:
1,请求成功,但是ajax走error:
原因:ajax中dataType定义了接口返回的类型,所以如果返回的字串就就会走error。
处理:
(1)dataType设置为json,后台接口返回一个对象
(2)dataType设置为text,后台接口返回字符串即可


2,ajax请求将参数封装成对象传递
(1)contentType设置为:'application/json'
(2)后台接口参数前加上注解@RequestBody:

------------------------------------------------------------------------------------------------------补充---------------------------------------------------------------------------------------------------------------------------------------------------------
1,获取当前用户
Object obj = SecurityUtils.getSubject().getPrincipal();
User sysUser = (User) obj;
2,获取token
SecurityUtils.getSubject().getSession().getId()
Springboot项目搭建(3)-shiro登录的更多相关文章
- SpringBoot 项目搭建(详细介绍+案例源码)
SpringBoot 项目搭建 SpringBoot 项目整合源码 SpringBoot 项目整合 一.项目准备 1.1 快速创建 SpringBoot 项目 1.2 标准项目结构图如下 1.3 添加 ...
- 在前后端分离的SpringBoot项目中集成Shiro权限框架
参考[1].在前后端分离的SpringBoot项目中集成Shiro权限框架 参考[2]. Springboot + Vue + shiro 实现前后端分离.权限控制 以及跨域的问题也有涉及
- SpringBoot之入门教程-SpringBoot项目搭建
SpringBoot大大的简化了Spring的配置,把Spring从配置炼狱中解救出来了,以前天天配置Spring和Mybatis,Springmvc,Hibernate等整合在一起,感觉用起来还是挺 ...
- SpringBoot项目搭建 + Jwt登录
临时接了一个小项目,有需要搭一个小项目,简单记录一下项目搭建过程以及整合登录功能. 1.首先拿到的是一个码云地址,里面是一个空的文件夹,只有一个 2. 拿到HTTPS码云项目地址链接,在IDEA中cl ...
- SpringBoot项目搭建与打包
一.环境准备 本地java环境jdk1.8 Maven版本3.5.2 IDE工具idea2017 二.SpringBoot微服务搭建 1.点击File >> New >> Pr ...
- springboot系列二、springboot项目搭建
一.官网快速构建 1.maven构建项目 1.访问http://start.spring.io/ 2.选择构建工具Maven Project.Spring Boot版本2.1.1以及一些工程基本信息, ...
- 从零开始的SpringBoot项目搭建
前言 今天是我加入博客园的第一天今天刚好学习到SpringBoot,就顺便记录一下吧 一.创建项目 1.创建工程 ① 通过File > New > Project,新建工程,选择Sprin ...
- springboot项目中使用shiro实现用户登录以及权限的验证
欢迎大家加入我的社区:http://t.csdn.cn/Q52km 社区中不定时发红包 更加高级的验证用户权限:用户表.角色表.权限表.多表联合:https://blog.csdn.net/weixi ...
- springboot项目搭建及常用技术整合
一.在你建立的工程下创建 Module 选择Spring initializr创建. 二.在Type处选择: Maven Project(项目的构建工具) 三.创建依赖时勾上web,mybatis,m ...
随机推荐
- 【Python】表白程序
程序链接:https://www.lanzous.com/i8xj5mh # 打包操作 # 安装pyinstaller # cmd输入 pip install pyinstaller # shift ...
- Spring-session+Redis解决Session共享
1. 保证Redis启动 2. 导入依赖 SpringBoot+Spring-Session+Redis <!--spring boot 与re ...
- restful设计参考
https://www.cnblogs.com/pyspark/p/8599210.html 以下查阅多处文档,思考总结: 所谓restful规范代表一种理想状态,首先对此种规范表示赞同,但应不忘实事 ...
- Postgresql 教程
Official 教程 关闭postgresql服务 PostgreSQL帐号 1. PostgreSQL 用户帐号和操作系统用户帐号是不同的,系统用户帐号是postgres. sudo -u pos ...
- 切换目录命令 - cd
1) 命令名称:cd 2) 英文原意:change directory 3) 命令所在路径:shell 内置命令 4) 执行权限:所有用户 5) 功能描述:切换目录 6) 语法: cd[目录名] 例子 ...
- 剑指offer 面试题 删除链表中重复的节点
题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后 ...
- JavaScript 运算,流程控制和循环
算数运算符 算术运算符 描叙 运算符 实例 加 + 10 + 20 = 30 减 - 10 – 20 = -10 乘 * 10 * 20 = 600 除 / 10 / 20 = 0.5 取余数 % 返 ...
- 慎用--skip-grant-tables命令
该命令作用是跳过授权表,也就是说谁都能进入mysql看到所有数据表,输入任意字符账号密码都可以 当忘记账号密码时可以使用改命令修改密码,但是要随用随关,重启mysql,不然服务器上会有很大的风险. 介 ...
- 易错之 Java字符串比较
字符串比较 不能直接用==判断,因为字符串内存地址不同,等号比较的是地址而不是大小 用equals()判断字符串是否相等 还可以用compareTo()比较
- 错误记录(三):Python
1,在函数中传入字典代替不定长参数 func(**d) # 传入时候要注意用**解包 2,一些常见的名字少用,容易和系统或其他包重名 3,递归中不能count+=1 #!/usr/bin/python ...