从零开始使用IDEA搭建Springboot+JPA+Swagger2.0+Logback+Lombok+Redis+Shiro1.4项目(七)

发布时间:2021-11-30 04:06:34



从零开始使用IDEA搭建Springboot+JPA+Swagger2.0+Logback+Lombok+Redis+Shiro1.4项目(七)
Springboot 整合 Shiro 1.4什么是Shiro配置添加 pom.xml 依赖配置 Shiro 相关文件ShiroConfig 配置文件自定义 Realm 文件异常处理配置文件
修改 Controller 类文件UserControllerRoleControllerAuthorityController

总结ShiroConfig认证和拦截Shiro 管理 Session权限设置登录人数控制
MyShiroRealmAuthenticationInfo 身份认证AuthorizationInfo 权限认证





Springboot 整合 Shiro 1.4
什么是Shiro

Shiro是一个功能强大且易于使用的Java安全框架,可执行身份验证,授权,加密和会话管理。借助Shiro易于理解的API,您可以快速轻松地保护任何应用程序,从最小的移动应用程序到最大的Web和企业应用程序。


配置
添加 pom.xml 依赖

添加Shiro所需的依赖。



org.apache.shiro
shiro-spring
1.4.0


org.apache.shiro
shiro-core
1.4.0


配置 Shiro 相关文件
ShiroConfig 配置文件

package com.demo.config;

import org.apache.shiro.mgt.SecurityManager;
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.web.session.mgt.DefaultWebSessionManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisManager;
import org.crazycake.shiro.RedisSessionDAO;
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;

/**
* @author Dawn
* @ClassName com.demo.config.ShiroConfig
* @Description
* @date 2019/7/11 15:27
*/

@Configuration
public class ShiroConfig {

@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
/*必须 设置securityManager*/
shiroFilterFactoryBean.setSecurityManager(securityManager);
/*没有登陆的用户只能访问登陆页面*/
shiroFilterFactoryBean.setLoginUrl("/login");
/*登录成功后要跳转的链接*/
shiroFilterFactoryBean.setSuccessUrl("/homepage");

/* 未授权 url*/
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
/*权限控制map*/
Map filterChainDefinitionMap = new LinkedHashMap<>();
/*开放登录接口*/
filterChainDefinitionMap.put("/login", "anon");
//放行Swagger2页面,需要放行这些
filterChainDefinitionMap.put("/swagger-ui.html", "anon");
filterChainDefinitionMap.put("/swagger-ui.html#/**", "anon");
filterChainDefinitionMap.put("/swagger-ui.html/**", "anon");
filterChainDefinitionMap.put("/swagger/**", "anon");
filterChainDefinitionMap.put("/webjars/**", "anon");
filterChainDefinitionMap.put("/swagger-resources/**", "anon");
filterChainDefinitionMap.put("/v2/**", "anon");
filterChainDefinitionMap.put("/static/**", "anon");

filterChainDefinitionMap.put("/logout", "logout");

filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

return shiroFilterFactoryBean;
}


/**
* 注入securityManager
*
* @return
*/
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
/*设置realm*/
securityManager.setRealm(myShiroRealm());
return securityManager;
}

/**
* 自定义身份认证 realm
* 必须写这个类并加上@Bean注解,目的是注入MyRealm
* 否则会影响MyRealm类中其他类的依赖注入
*
* @return
*/
@Bean
public MyShiroRealm myShiroRealm() {
return new MyShiroRealm();
}

@Bean
public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}

}

自定义 Realm 文件

package com.demo.config;

import com.demo.dao.AuthorityRepository;
import com.demo.dao.UserRepository;
import com.demo.entity.Role;
import com.demo.entity.User;

import org.apache.shiro.SecurityUtils;
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.*;

/**
* @author Dawn
* @ClassName com.demo.config.MyShrioRealm
* @Description
* @date 2019/7/11 16:03
*/


public class MyShiroRealm extends AuthorizingRealm {

@Autowired
private UserRepository userRepository;


@Autowired
private AuthorityRepository authorityRepository;




/**
* 获取身份验证信息
* Shiro中,最终是通过Realm来获取应用程序中的用户、角色及权限信息的
* @param authenticationToken
* @return
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) {
System.out.println("-----------------身份认证方法--------------");
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
User user = userRepository.findUserByAccount(token.getUsername());
if (user==null){
throw new UnknownAccountException("用户名不正确");
}else if (!user.getPassword().equals(new String((char[])token.getCredentials()))){
throw new IncorrectCredentialsException("密码不正确");
}
return new SimpleAuthenticationInfo(token.getPrincipal(),user.getPassword(),getName());
}

/**
* 获取授权信息
*
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("-------权限认证---------");
String account = (String) SecurityUtils.getSubject().getPrincipal();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
/*获得该用户角色*/
List role_names = userRepository.findRoleNameByAccount(account);
Set roleSet = new HashSet<>();
/*需要将 role 封装到 Set 作为 info.setRoles() 的参数*/
roleSet.addAll(role_names);
/*设置该用户拥有的角色*/
info.setRoles(roleSet);
/*设置权限*/
List roles = userRepository.findUserByAccount(account).getRoles();
Set authoritySet = new HashSet<>();
for (Role role:roles
) {
List authorities = authorityRepository.findAuthoritiesUrlByRoleId(role.getId());
authoritySet.addAll(authorities);
}
info.setStringPermissions(authoritySet);
return info;
}
}


异常处理配置文件

package com.demo.config;

import org.apache.shiro.authz.AuthorizationException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;

/**
* @author Dawn
* @ClassName com.demo.config.GlobalDefaultExceptionHandler
* @Description
* @date 2019/7/16 16:27
*/

@ControllerAdvice
public class GlobalDefaultExceptionHandler {

@ExceptionHandler(AuthorizationException.class)
@ResponseBody
public String defaultExceptionHandler(HttpServletRequest req, Exception e){
return "对不起,你没有访问权限!";
}
}


修改 Controller 类文件

@RequiresPermissions:调用当前方法所需要的权限
@RequiresRoles:调用当前方法所需要的角色


UserController

package com.demo.controller;

import com.demo.entity.User;
import com.demo.service.AuthorityService;
import com.demo.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Api(tags = "用户管理")
@RestController
public class UserController {

@Autowired
UserService userService;

@Autowired
AuthorityService authorityService;

@ApiOperation("用户登录")
@GetMapping(value = "/login")
public Map userLogin(HttpServletRequest request,
@ApiParam(required = true,name = "account",value = "账户")@RequestParam("account")String account,
@ApiParam(required = true,name = "password",value = "密码") @RequestParam("password")String password){
String msg="";
Map map = new HashMap<>();
try {
UsernamePasswordToken token = new UsernamePasswordToken(account,password);
char[] thePasswordChar = token.getPassword();
String thePassword = thePasswordChar.toString();
SecurityUtils.getSubject().login(token);
token.setRememberMe(true);
map.put("status",200);
User user = userService.findUserByAccount(account);
SecurityUtils.getSubject().getSession().setAttribute("account",user.getAccount());
/*request.getSession().setAttribute("account",token.getUsername());*/
}catch (UnknownAccountException e){
msg = "UnknownAccountException -- > 账号不存在:";
map.put("status","异常:账号不存在");
}catch (IncorrectCredentialsException e){
msg = "IncorrectCredentialsException -- > 密码不正确:";
map.put("status","异常:密码不正确");
}catch (LockedAccountException e){
msg = "LockedAccountException -- > 账号被锁定:";
map.put("status","异常:账号被锁定");
}catch (Exception exception){
msg = "else >> "+exception;
System.out.println("else -- >" + exception);
}

return map;
}

@ApiOperation("用户信息")
@GetMapping(value = "/user/get")
public Map userGet(HttpServletRequest request){
Map map = new HashMap<>();
map.put("account",SecurityUtils.getSubject().getSession().getAttribute("account"));
return map;
}

@ApiOperation("用户登出")
@GetMapping(value = "/logout")
public String userLogout(HttpServletRequest request){

return "0";
}

@RequiresPermissions(value = {"/menu_user","/user/add","/menu"},logical = Logical.OR)
@ApiOperation("新增一个用户")
@PostMapping(value = "user")
public User insertNewUser(@ApiParam(required = true,name = "user_name",value = "用户名")@RequestParam("user_name") String user_name,
@ApiParam(required = true,name = "account",value = "帐号")@RequestParam("account") String account,
@ApiParam(required = true,name = "password",value = "密码")@RequestParam("password")String password,
@ApiParam(required = true,name = "phone",value = "电话")@RequestParam("phone") String phone,
@ApiParam(required = true,name = "age",value = "年龄")@RequestParam("age") Integer age,
@ApiParam(required = true,name = "role_id",value = "角色id")@RequestParam("role_id") List role_ids,
@ApiParam(required = true,name = "status",value = "角色状态")@RequestParam("status")Integer status ) {

return userService.insertNewUser(user_name, account,password, phone, age, role_ids,status);
}

@RequiresPermissions(value = {"/menu_user","/user/delete","/menu"},logical = Logical.OR)
@ApiOperation("根据id删除一个用户")
@DeleteMapping(value = "user/{id}")
public void deleteUserById(@ApiParam(required = true,name = "id",value = "用户id")@PathVariable("id") Integer id) {
userService.deleteUserById(id);
}

@RequiresPermissions(value = {"/menu_user","/user/update","/menu"},logical = Logical.OR)
@ApiOperation("根据id修改一个用户")
@PutMapping(value = "user/{id}")
public User updateUserById(@ApiParam(required = true,name = "id",value = "id")@PathVariable("id") Integer id,
@ApiParam(required = true,name = "user_name",value = "用户名")@RequestParam("user_name") String user_name,
@ApiParam(required = true,name = "account",value = "帐号")@RequestParam("account") String account,
@ApiParam(required = true,name = "password",value = "密码")@RequestParam("password")String password,
@ApiParam(required = true,name = "phone",value = "电话")@RequestParam("phone") String phone,
@ApiParam(required = true,name = "age",value = "年龄")@RequestParam("age") Integer age,
@ApiParam(required = true,name = "role_id",value = "角色id")@RequestParam("role_id") List role_ids) {
return userService.updateUserById(id, user_name, account,password, phone, age, role_ids);
}

@RequiresPermissions(value = {"/menu_user","/user/find","/menu"},logical = Logical.OR)
@ApiOperation("查找所有用户")
@GetMapping(value = "users")
public List findAllUser() {
return userService.findAllUser();
}

@RequiresPermissions(value = {"/menu_user","/user/find","/menu"},logical = Logical.OR)
@ApiOperation("根据id查找用户")
@GetMapping(value = "/user/{id}")
public User findUserById(@ApiParam(required = true,name = "id",value = "id")@PathVariable("id") Integer id) {
return userService.findUserById(id);
}

@RequiresPermissions(value = {"/menu_user","/user/find","/menu"},logical = Logical.OR)
@ApiOperation("根据帐号查找用户")
@GetMapping(value = "/user/account")
public User findUserByAccount(@ApiParam(required = true,name = "account",value = "帐号")@RequestParam("account") String account){
return userService.findUserByAccount(account);
}


@RequiresPermissions(value = {"/menu_user","/user/find","/menu"},logical = Logical.OR)
@ApiOperation("根据关键词查找角色")
@GetMapping(value = "/user/keyword")
public User findUserByKeyword(@ApiParam(required = true,name = "account",value = "帐号")@RequestParam("account")String account,
@ApiParam(required = true,name = "phone",value = "电话")@RequestParam("phone")String phone,
@ApiParam(required = true,name = "user_name",value = "用户名")@RequestParam("user_name")String user_name){
return userService.findUserByKeyword(account, phone, user_name);
}

}


RoleController

package com.demo.controller;

import com.demo.entity.Role;
import com.demo.service.RoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Api(tags = "角色管理")
@RestController
public class RoleController {

@Autowired
RoleService roleService;

@RequiresPermissions(value = {"/menu_role","/role/add","/menu"},logical = Logical.OR)
@ApiOperation("新增一个角色")
@PostMapping(value = "/role/insert")
public Role insertNewRole(@ApiParam(required = true,name = "role_name",value = "角色名")@RequestParam("role_name") String role_name,
@ApiParam(required = true,name = "parent_role_id",value = "父级角色id,无父级则为0")@RequestParam("parent_role_id") Integer parent_role_id,
@ApiParam(required = true,name = "authority_ids",value = "拥有的权限") @RequestParam("authority_ids") List authority_ids,
@ApiParam(required = true,name = "status",value = "角色状态") @RequestParam("status") Integer status) {
return roleService.insertNewRole(role_name, parent_role_id,authority_ids,status);
}


@RequiresPermissions(value = {"/menu_role","/role/delete","/menu"},logical = Logical.OR)
@ApiOperation("根据id删除角色")
@DeleteMapping(value = "/role/{id}")
public void deleteRoleById(@ApiParam(required = true,name = "id",value = "id")@PathVariable("id") Integer id) {
roleService.deleteRoleById(id);
}

@RequiresPermissions(value = {"/menu_role","/role/update","/menu"},logical = Logical.OR)
@ApiOperation("根据id修改角色")
@PutMapping(value = "/role/{id}")
public Role updateRoleById(@ApiParam(required = true,name = "id",value = "id")@PathVariable("id") Integer id,
@ApiParam(required = true,name = "role_name",value = "角色名")@RequestParam("role_name") String role_name,
@ApiParam(required = true,name = "parent_role_id",value = "父级角色id,无父级则为0")@RequestParam("parent_role_id") Integer parent_role_id,
@ApiParam(required = true,name = "authority_ids",value = "拥有的权限id")@RequestParam("authority_ids")List authority_ids) {
return roleService.updateRoleById(id, role_name, parent_role_id,authority_ids);
}


@RequiresPermissions(value = {"/menu_role","/role/find","/menu"},logical = Logical.OR)
@ApiOperation("查找所有角色")
@GetMapping(value = "/role")
public List findAllRole() {
return roleService.findAllRole();
}

@RequiresPermissions(value = {"/menu_role","/role/find","/menu"},logical = Logical.OR)
@ApiOperation("根据id查找角色")
@GetMapping(value = "/role/{id}")
public Role findRoleById(@ApiParam(required = true,name = "id",value = "id")@PathVariable("id") Integer id) {
return roleService.findRoleById(id);
}

/* @PostMapping(value = "/role/insertRole")
public Role insert(@RequestParam("role_name") String role_name, @RequestParam("parent_role_id") Integer parent_role_id, @RequestParam("id1") Integer id1, @RequestParam("id2") Integer id2) {
return roleService.insert(role_name, parent_role_id, id1, id2);
}

@PostMapping(value = "/role/insertRoleInsert")
public Role insertInsert(@RequestParam("role_name") String role_name, @RequestParam("parent_role_id") Integer parent_role_id, @RequestParam("id1") Integer id1) {
return roleService.insertInsert(role_name, parent_role_id, id1);
}*/

/*@RequiresPermissions(value = {"/menu_role","/role/delete","/menu"},logical = Logical.OR)
@ApiOperation("根据父级id查找角色")
@GetMapping(value = "/role/parent_id/{id}")
public List findRolesByParentId(@ApiParam(required = true,name = "id",value = "id")@PathVariable("id") Integer id) {
return roleService.findRolesByParentId(id);
}*/

}


AuthorityController

package com.demo.controller;

import com.demo.entity.Authority;
import com.demo.service.AuthorityService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Api(tags = "权限管理")
@RestController
public class AuthorityController {

@Autowired
AuthorityService authorityService;

/*@RequiresPermissions("/authority/add")*/
/*@ApiOperation("权限新增")
@PostMapping(value = "/authority")
public Authority insertNewAuthority(@ApiParam(required = true, name = "authority_name", value = "权限名") @RequestParam("authority_name") String authority_name,
@ApiParam(required = true, name = "url", value = "请求路径") @RequestParam("url") String url,
@ApiParam(required = true, name = "code", value = "编码") @RequestParam("code") String code,
@ApiParam(required = true, name = "status", value = "状态") @RequestParam("status") Integer status,
@ApiParam(required = true, name = "parent_authority_id", value = "父级权限id,无父级则为0") @RequestParam("parent_authority_id") Integer parent_authority_id) {
return authorityService.insertNewAuthority(authority_name, url, code, status, parent_authority_id);

}*/

/* @RequiresPermissions("/authority/delete")*/
/*@ApiOperation("根据id删除权限")
@DeleteMapping(value = "/authority/{id}")
public void deleteAuthorityById(@ApiParam(required = true,name = "id",value = "要删除的权限id")@PathVariable("id") Integer id) {
authorityService.deleteAuthorityById(id);
}*/

@RequiresPermissions(value = {"/authority/update","/menu_authority","/menu"},logical = Logical.OR)
@ApiOperation("根据id修改权限")
@PutMapping(value = "/authority/{id}")
public Authority updateAuthorityById(@ApiParam(required = true,name = "id",value = "要修改的权限id")@PathVariable("id") Integer id,
@ApiParam(required = true,name = "authority_name",value = "权限名")@RequestParam("authority_name") String authority_name,
@ApiParam(required = true,name = "url",value = "请求路径")@RequestParam("url") String url,
@ApiParam(required = true,name = "code",value = "编码")@RequestParam("code") String code,
@ApiParam(required = true,name = "status",value = "状态") @RequestParam("status") Integer status,
@ApiParam(required = true,name = "parent_authority_id",value = "父级权限id,无父级则为0")@RequestParam("parent_authority_id") Integer parent_authority_id) {
return authorityService.updateAuthorityById(id, authority_name, url, code, status, parent_authority_id);

}

@RequiresPermissions(value = {"/authority/find","/menu_authority","/menu"},logical = Logical.OR)
@ApiOperation("查询所有权限")
@GetMapping(value = "/authority")
public List findAllAuthority() {
return authorityService.findAllAuthority();
}

@RequiresPermissions(value = {"/authority/find","/menu_authority","/menu"},logical = Logical.OR)
@ApiOperation("根据id查询权限")
@GetMapping(value = "/authority/{id}")
public Authority findAuthorityById(@ApiParam(required = true,name = "id",value = "权限id")@PathVariable("id") Integer id) {
return authorityService.findAuthorityById(id);
}

/* @ApiOperation("根据角色id查找权限")
@GetMapping(value = "/authority/find/parent")
public List findParentAuthorityByRoleId(@RequestParam("user_id")Integer user_id){
return authorityService.findParentAuthorityByRoleId(user_id);
}*/


/* @GetMapping(value = "/authority/find/child")
public List findChildAuthorityByAuthorityId(@RequestParam("authority_id")Integer authority_id){
return authorityService.findChildAuthorityByAuthorityId(authority_id);
}*/

}


总结
ShiroConfig
认证和拦截

anonShiro的认证配置的过滤器之一,指定排除认证的uri,设置anon属性的路径不会被拦截。如果使用Swagger进行测试时,需要将所有相关界面放行。


filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/swagger-ui.html", "anon");

authcShiro的认证配置的过滤器之一,指定需要认证的uri,如下配置表示所有请求被拦截,只有登录之后才能使用。需要放在所有设置最后,如果先设置拦截,再设置放行,则放行的界面不起作用。


filterChainDefinitionMap.put("/**", "authc");

Shiro 管理 Session

最开始我在配置Shiro时,认证成功后直接将用户信息存到了Session容器中。查阅资料写博客的时候,发现这种做法不严谨,应该使用Shiro来管理Session会话对象,要获取Session也应该通过Shiro,传统的Session中不存在保存的值。
由于使用Redis管理Session,在GithubShiro-Redis开源插件可供使用,在pom.xml配置相关设置后即可使用。


添加 pom.xml 依赖



org.crazycake
shiro-redis
2.4.2.1-RELEASE


修改 ShiroConfig 类


@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
/*设置realm*/
securityManager.setRealm(myShiroRealm());
/*自定义缓存实现,使用redis*/
securityManager.setCacheManager(cacheManager());
/*自定义session管理,使用redis*/
securityManager.setSessionManager(sessionManager());
return securityManager;
}

/**
* cacheManager 缓存 redis实现
* 使用的是shiro-redis开源插件
* @return
*/
public RedisCacheManager cacheManager(){
RedisCacheManager redisCacheManager = new RedisCacheManager();
redisCacheManager.setRedisManager(redisManager());
return redisCacheManager;
}

/**
* 配置shiro redisManager
* 使用的是shiro-redis开源插件
*
* @return
*/
public RedisManager redisManager(){
RedisManager redisManager = new RedisManager();
redisManager.setHost("localhost");
redisManager.setPort(6379);
redisManager.setExpire(1800);//缓存过期时间
redisManager.setTimeout(0);
return redisManager;
}

/**
* Session Manager
* 使用的是shiro-redis开源插件
*/
@Bean
public DefaultWebSessionManager sessionManager(){
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
sessionManager.setSessionDAO(redisSessionDAO());
return sessionManager;
}

/**
* RedisSessionDAO shiro sessionDao层的实现 通过redis
* 使用的是shiro-redis开源插件
*/
@Bean
public RedisSessionDAO redisSessionDAO() {
RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
redisSessionDAO.setRedisManager(redisManager());
return redisSessionDAO;
}

修改 Controller 类中的写法


/*原来的写法*/
request.getSession().setAttribute("account",token.getUsername());
/*修改后的写法*/
SecurityUtils.getSubject().getSession().setAttribute("account",token.getUsername());

权限设置

配置完之后 @RequiresRoles@RequiresPermissions,有些用户没有权限也能进行访问。
需要借助SpringAOP扫描使用Shiro注解的类,并在必要的时候进行安全逻辑验证开启注解。配置以下两个 @Bean 就可以让注解生效。


@Bean
@ConditionalOnMissingBean
public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
return defaultAdvisorAutoProxyCreator;
}

@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
return authorizationAttributeSourceAdvisor;
}

登录人数控制

这个设置在我刚开始学*配置Shiro时没有注意过,也是翻阅资料的时候才注意到。按道理来说这个限制是很有必要的,但是作为一个本地小项目,配置了也看不到效果,日后再进行研究。


添加 pom.xml 依赖



com.alibaba
fastjson
1.2.13


ShiroConfig 配置


@Bean
public KickoutSessionControlFilter kickoutSessionControlFilter() {
KickoutSessionControlFilter kickoutSessionControlFilter = new KickoutSessionControlFilter();
kickoutSessionControlFilter.setCacheManager(cacheManager());
kickoutSessionControlFilter.setSessionManager(sessionManager());
kickoutSessionControlFilter.setKickoutAfter(false);
kickoutSessionControlFilter.setMaxSession(1);
kickoutSessionControlFilter.setKickoutUrl("/auth/kickout");
return kickoutSessionControlFilter;
}

KickoutSessionControlFilter 类
详细配置信息见https://www.cnblogs.com/caichaoqi/p/8900677.html


MyShiroRealm

自定义身份认证有两种:AuthenticationInfoAuthorizationInfo,两者长得很像,AuthenticationInfo用于身份认证,AuthorizationInfo用于权限认证。


AuthenticationInfo 身份认证

传统的方式是人工写方法进行帐号和密码的验证,使用Shiro进行权限认证,则将帐号和密码存放到token中,使用AuthenticationInfo 认证帐号和密码是否匹配。


AuthorizationInfo 权限认证

登录成功后,在AuthorizationInfo 中进行权限认证。通过用户的帐号,搜索数据库进行角色和权限匹配,赋予该用户以数据库中对应的角色和权限。配合 @RequiresPermissions@RequiresRoles注解,对方法的调用进行分配和控制。

相关文档

  • Educational Codeforces Round 96 (Rated for Div. 2)[A-E]题解
  • 教师党员公开承诺书四篇
  • 趣步3.1.1怎么买糖果
  • 试管婴儿麻醉取卵有哪些影响2018麻醉会不会对卵子有影响
  • 2020年个人季度工作总结范文精选5篇
  • 派生类、基类和对象成员的构造/析构顺序
  • 我的兴趣爱好作文介绍我的爱好
  • 中考满分作文:你有属于自己的光芒
  • 数控技术实习报告
  • 有关刚的四字成语大全
  • 彩铅画的特点有哪些基本技法
  • 越美越愚蠢美文
  • 澳洲灰指甲水使用说明澳洲灰指甲水怎么用?
  • 女性调理身体吃六味地黄丸效果如何
  • 幼儿园安全月工作计划精选4篇
  • 羊和狼作文300字8篇
  • 【数据结构和算法17】拓扑排序
  • 给亲爱的乌丽娜的一封信
  • React-Native之 修改包名(Android)
  • 自己的花是让别人看的教学设计模板
  • 网络爬虫入门篇
  • 2017年12月英语四级作文常用谚语(五)
  • 餐饮业减税申请书
  • 青菜苔可以吃吗?青菜苔怎么做好吃?
  • 写日记的好处有哪些
  • 使用DSP/BIOS数据类型
  • 推荐安全承诺书3篇
  • 感恩教师节沙画视频
  • 2018小孩冬天穿什么鞋子好小孩童靴哪种款式好
  • 心理测试标准
  • 猜你喜欢

  • 湖北好的留学中介
  • go语言基础之指针和new
  • 美国*惯用语219:走,一起吃午饭 -(韦博分享)
  • 十七届四中全会 中共中央关于加强和改进新形势下党的建设若干重大问题的决定
  • 拜托了班长取景的学校是哪 拜托了班长拍摄地点汇总
  • 国内大型循环流化床锅炉现状及设计运行特性研究
  • Unit1 Getting along with others Grammar and usage 2
  • 【高考64篇情景默写】 之《离骚》(精品)
  • 红嘴蓝鹊 生长繁殖
  • 关于旅游管理应用型本科加强实践教学环节的思考
  • 2019年高考生物一轮复*选练*题3含解析新人教版
  • 2015安徽合肥市包河区事业单位招聘笔试时间
  • 化妆品涨价15% 5免费美容法
  • no model named shapefile
  • Mybatis返回主键的几种方式
  • 作文让论据活起来
  • 烟台天下情文化艺术有限公司企业信用报告-天眼查
  • 情意美的句子
  • 人教版数学五年级下册折线统计图的认识
  • 排毒减肥茶的制作方法
  • 论索尔·贝娄长篇小说中的生命意识
  • 湛江市世华房地产代理有限公司开发区澳海居分店企业信用报告-天眼查
  • 北京笃达技术有限公司企业信息报告-天眼查
  • 优秀中班教案健康:做个讲卫生的好孩子
  • 高考语文二轮复* 第1部分 核心突破 专题3 古代诗歌鉴赏 第4讲 比较阅读课件
  • 教师节的礼物作文500字教师节的礼物作文
  • 13张麻将技巧口诀_打麻将的公式
  • 2018-创业之星实训心得体会范文-范文模板 (3页)
  • 十三章通关解析 小时代手游13.7曲解五星通关
  • 区党委干部就职演讲与区党工委书记瑟肽晔鲋笆隽?ǜ妯多篇范文)汇编
  • 苏教版五年级语文下册《文 11 郑和远航》优质课课件_8
  • 精美PPT 108个模板058(2)精品
  • 第一学期人教版四年级上册英语PEP期末试卷练*
  • 11 我多想去看看课件.ppt
  • 视频号快速出圈运营指南,快速上手视频号:国仁楠哥
  • 苏少版小学二年级音乐上册(简谱)两只小象 打掌掌_课件1
  • 对加强班主任队伍建设的思考
  • 重庆市大学城第一中学校高中数学培优补差练*5 理(无答案)
  • 中外经典电影与艺术赏析
  • 三年级下语文课件-画杨桃3 _北京课改版
  • 幼儿园大班音乐《迷路的小花鸭》优秀说课稿
  • 微信文章图文排版指南
  • 电脑版