进阶教程:

1. springboot+shiro+redis(单机redis版)整合教程

2. springboot+shiro+redis(集群redis版)整合教程

3.springboot+shiro+redis(单机redis版)整合教程-续(添加动态角色权限控制)

本教程整合环境: java8 maven

开发工具: idea

版本: springboot 1.5.15.RELEASE

注:

1.本教程数据操作是模拟数据库操作,并没有真正进行持久化,自行修改即可。

2.角色权限验证未实现,只实现基本的登录验证,自行扩展即可。

项目结构:

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>webapp</groupId>
<artifactId>springboot-shiro</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <name>springboot-shiro</name>
<description>Demo project for Spring Boot</description> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.15.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>

application.yml:

server:
port: 1000

User.java:

package webapp.model;

import lombok.Data;

/**
* Created by Administrator on 2018/9/5.
*/
@Data
public class User {
private Long id;
private String userName;
private String password;
}

UserService.java:

package webapp.service;

import webapp.model.User;

/**
* Created by Administrator on 2018/9/5.
*/
public interface UserService {
User findOneByUserName(String userName);
}

UserServiceImpl.java:

package webapp.service.impl;

import org.springframework.stereotype.Service;
import webapp.model.User;
import webapp.service.UserService; /**
* Created by Administrator on 2018/9/5.
*/
@Service
public class UserServiceImpl implements UserService { @Override
public User findOneByUserName(String userName) {
User user = new User();
user.setId(1L);
user.setUserName("007少侠");
user.setPassword("123456");
return user;
}
}

UserController.java:

package webapp.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import webapp.service.UserService; import java.io.Serializable; /**
* Created by Administrator on 2018/9/5.
*/
@RestController
@RequestMapping("/core/user")
public class UserController {
@Autowired
private UserService userService; /**
* 登录
* @param
* @return
*/
@GetMapping("/login")
public String login(String userName, String password) {
System.out.println("登录" + userName); Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
subject.login(token); Session session = subject.getSession();
Serializable sessionId = session.getId();
System.out.println("登录成功 -> " + sessionId); return userName + "[" + sessionId + "]";
} @GetMapping("/logout")
public String logout() {
SecurityUtils.getSubject().logout();
return "退出登录成功";
} /**
* 获取当前登录用户
* @return
*/
@GetMapping("/findUser")
public String findUser() {
Subject subject = SecurityUtils.getSubject();
PrincipalCollection collection = subject.getPrincipals();
if (null != collection && !collection.isEmpty()) {
String userName = (String) collection.iterator().next();
System.out.println("获取当前登录用户" + userName);
return userService.findOneByUserName(userName).toString();
}
return "{\n" +
" \"codeEnum\": \"OVERTIME\",\n" +
" \"code\": 0,\n" +
" \"data\": null,\n" +
" \"msg\": \"未登陆/登陆超时\",\n" +
" \"success\": false\n" +
"}";
}
}

下面为shiro基本配置:

UserShiroRealm.java:

package webapp.shiro;

import org.apache.shiro.SecurityUtils;
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.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.springframework.beans.factory.annotation.Autowired;
import webapp.model.User;
import webapp.service.UserService; import java.util.Collection; /**
* Created by Administrator on 2018/9/5.
*/
public class UserShiroRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
@Autowired
private SessionDAO sessionDAO; /**
* 角色权限和对应权限添加
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
} /**
* 用户认证
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//加这一步的目的是在Post请求的时候会先进认证,然后在到请求
if (authenticationToken.getPrincipal() == null) {
return null;
} String userName = authenticationToken.getPrincipal().toString(); //只允许同一账户单个登录
Subject subject = SecurityUtils.getSubject();
Session nowSession = subject.getSession();
Collection<Session> sessions = sessionDAO.getActiveSessions();
if(sessions != null && sessions.size() > 0) {
for (Session session : sessions) {
if (!nowSession.getId().equals(session.getId()) && (session.getTimeout() == 0
|| userName.equals(String.valueOf(session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY))))) {
sessionDAO.delete(session);
}
}
} User user = userService.findOneByUserName(userName);
if (user == null) {
return null;
} else {
//这里验证authenticationToken和simpleAuthenticationInfo的信息
return new SimpleAuthenticationInfo(userName, user.getPassword(), getName());
}
}
}

ShiroCoreController.java:

package webapp.shiro;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; /**
* Created by Administrator on 2018/9/5.
*/
@RestController
public class ShiroCoreController {
@GetMapping("/loginUnAuth")
public String loginUnAuth() {
return "{\n" +
" \"codeEnum\": \"OVERTIME\",\n" +
" \"code\": 0,\n" +
" \"data\": null,\n" +
" \"msg\": \"未登陆/登陆超时\",\n" +
" \"success\": false\n" +
"}";
}
@GetMapping("/authorUnAuth")
public String authorUnAuth() {
return "{\n" +
" \"codeEnum\": \"ERR_PERMISSIONS\",\n" +
" \"code\": -2,\n" +
" \"data\": null,\n" +
" \"msg\": \"无此权限\",\n" +
" \"success\": false\n" +
"}";
}
}

shiro配置类ShiroConfiguration.java:

package webapp.conf;

import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
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.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import webapp.shiro.UserShiroRealm; import java.util.HashMap; /**
* shiro配置类
* Created by Administrator on 2018/9/5.
*/
@Configuration
public class ShiroConfiguration { //将自己的验证方式加入容器
@Bean
public UserShiroRealm userShiroRealm() {
return new UserShiroRealm();
} @Bean
public MemorySessionDAO getMemorySessionDAO() {
return new MemorySessionDAO();
} @Bean
public SimpleCookie getSimpleCookie() {
SimpleCookie simpleCookie = new SimpleCookie();
simpleCookie.setName("SHRIOSESSIONID");
return simpleCookie;
} @Bean
public MemoryConstrainedCacheManager memoryConstrainedCacheManager() {
return new MemoryConstrainedCacheManager();
} //配置shiro session 的一个管理器
@Bean
public DefaultWebSessionManager getDefaultWebSessionManager() {
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
sessionManager.setSessionDAO(getMemorySessionDAO());
sessionManager.setGlobalSessionTimeout(-1000); //session有效期 默认值1800000 30分钟 1800000毫秒 -1000表示永久
SimpleCookie simpleCookie = getSimpleCookie();
simpleCookie.setHttpOnly(true); //设置js不可读取此Cookie
simpleCookie.setMaxAge(3 * 365 * 24 * 60 * 60); //3年 cookie有效期
sessionManager.setSessionIdCookie(simpleCookie);
return sessionManager;
} //配置核心安全事务管理器
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(userShiroRealm());
manager.setCacheManager(memoryConstrainedCacheManager());
manager.setSessionManager(getDefaultWebSessionManager());
return manager;
} //加入注解的使用,不加入这个注解不生效
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
return authorizationAttributeSourceAdvisor;
} //Filter工厂,设置对应的过滤条件和跳转条件
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean() {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager());
HashMap<String, String> map = new HashMap<>();
//登出
//map.put("/logout", "logout");
//认证 /###/@@@/**
map.put("/api/**", "authc"); //登录认证不通过跳转
shiroFilterFactoryBean.setLoginUrl("/loginUnAuth");
//首页
//shiroFilterFactoryBean.setSuccessUrl("/index");
//权限认证不通过跳转
shiroFilterFactoryBean.setUnauthorizedUrl("/authorUnAuth");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
return shiroFilterFactoryBean;
}
}

启动项目,访问相关接口校验是否成功:

登录接口:http://localhost:1000/core/user/login?userName=002&password=123456

  返回:002[42c6d423-e48e-4164-b17d-0cbc0f9ca832]

获取用户:http://localhost:1000/core/user/findUser

  返回:User(id=1, userName=007少侠, password=123456)

退出登录:http://localhost:1000/core/user/logout

  返回:退出登录成功

springboot+shiro整合教程的更多相关文章

  1. Springboot + shiro 整合之Url拦截设置(转)

    shiro 整合到springboot 还是比较简单的,只需要新建一个spring-shiro.xml的配置文件: <span style="font-size:14px;" ...

  2. springboot+shiro+redis(单机redis版)整合教程-续(添加动态角色权限控制)

    相关教程: 1. springboot+shiro整合教程 2. springboot+shiro+redis(单机redis版)整合教程 3. springboot+shiro+redis(集群re ...

  3. springboot+shiro+redis(集群redis版)整合教程

    相关教程: 1. springboot+shiro整合教程 2. springboot+shiro+redis(单机redis版)整合教程 3.springboot+shiro+redis(单机red ...

  4. springboot+shiro+redis(单机redis版)整合教程

    相关教程: 1. springboot+shiro整合教程 2. springboot+shiro+redis(集群redis版)整合教程 3.springboot+shiro+redis(单机red ...

  5. springboot+shiro

    作者:纯洁的微笑 出处:http://www.ityouknow.com/ 这篇文章我们来学习如何使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公 ...

  6. Spring Cloud之路:(七)SpringBoot+Shiro实现登录认证和权限管理

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/sage_wang/article/details/79592269一.Shiro介绍1.Shiro是 ...

  7. (八) SpringBoot起飞之路-整合Shiro详细教程(MyBatis、Thymeleaf)

    兴趣的朋友可以去了解一下前几篇,你的赞就是对我最大的支持,感谢大家! (一) SpringBoot起飞之路-HelloWorld (二) SpringBoot起飞之路-入门原理分析 (三) Sprin ...

  8. springboot+shiro+redis项目整合

    介绍: Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码学和会话管理.使用Shiro的易于理解的API,您可以快速.轻松地获得任何应用程序,从最小的移动应用程序到最 ...

  9. springboot 与 shiro 整合 (简洁版)

    前言: 网上有很多springboot 与 shiro 整合的资料,有些确实写得很好, 对学习shiro和springboot 都有很大的帮助. 有些朋友比较省事, 直接转发或者复制粘贴.但是没有经过 ...

随机推荐

  1. SQL Server 2008 R2升级到SQL Server 2012 SP1

    1.建议对生产环境对的数据库升级之前做好备份,以防不测. 2.从SQL Server 2008 R2 升级到SQL Server 2012 SP1,需要先安装SQL Server 2008 R2 的S ...

  2. 【Java】通用版URLConnection 带cookie下载PDF等资源文件

    /**** * 下载pdf文件 */ public static void downloadNet(String urlStr, String fileName, String savePath) t ...

  3. mysql 添加外键时 error 150 问题总汇

    当你试图在mysql中创建一个外键的时候,这个出错会经常发生,这是非常令人沮丧的.像这种不能创建一个.frm 文件的报错好像暗示着操作系统的文件的权限错误或者其它原因,但实际上,这些都不是的,事实上, ...

  4. hdu3038(种类并查集,推荐)

    题目大意:有n次询问,给出a到b区间的总和,问这n次给出的总和中有几次是和前面已近给出的是矛盾的?? 很有意思的一道题目,要是没有做过种类并查集,我肯定会以为这种题目是线段树题目...... 思路:我 ...

  5. 02-老马jQuery教程-jQuery事件处理

    1. 绑定简单事件 在DOM中DOM0级绑定事件的方式是直接给事件属性赋值,但是这样有个缺点就是每次指定的事件处理程序会把之前的覆盖掉. jQuery简单绑定事件的方式,可以让我绑定多个事件处理程序跟 ...

  6. Ubuntu常用安装源

    sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak #备份 sudo vim /etc/apt/sources.list #修改 sudo ...

  7. git学习(六):git stash

    对于更改操作的处理 使用git status命令可以看到当前工作区的状态: git status // 查看工作区的状态 // 对于已经git add工作区中文件 git reset HEAD < ...

  8. 配置Chrome Workspace功能

    配置Chrome Workspace功能 Chrome Workspace功能是将在Chrome开发者工具(F12)中对文档的修改直接应用于对应文件中.由于Chrome并不知道当然文档对应用的文件为哪 ...

  9. Java Rest客户端框架有哪些

    HttpClient HtmlUnit Jsoup HttpUrlConnection(java原生) Http4j

  10. 什么是API网关?

    版权声明:本文为博主原创文章,未经博主允许不得转载. http://blog.csdn.net/lcx216/article/details/52913645 1.API网关介绍 API网关是一个服务 ...