<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.4.0</version>
</dependency>
2:自定义Realm继承AuthorizingRealm
实现两个方法doGetAuthorizationInfo和doGetAuthenticationInfo
doGetAuthorizationInfo: 该方法用于定义用户在shiro中的安全权限,也就是说我们可以在这个方法中告诉shiro当前登录的用户具有访问哪些路径或资源的权限;
package com.example.realm;
import com.example.entity.Permission;
import com.example.entity.Role;
import com.example.entity.User;
import com.example.service.PermissionService;
import com.example.service.RoleService;
import com.example.service.UserService;
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.util.StringUtils;
import javax.annotation.Resource;
import java.util.*;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username =(String) getAvailablePrincipal(principals);
User user = userService.selectByUserName(username);
//查询用户对应的角色信息
List<Role> roleList=roleService.selectRoleList(user.getUid());
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
//系统角色
// Set<String> roles=new HashSet<>();
// //角色所用户的权限
// Set<String> permissions=new HashSet<>();
for(Role role:roleList){
info.addRole(role.getRname());
// roles.add(role.getRname());
List<Permission> permissionList=permissionService.selectPermissionList(role.getRid());
for(Permission permission:permissionList){
info.addStringPermission(permission.getPname());
// permissions.add(permission.getPname());
}
// info.setRoles(roles);
// info.setStringPermissions(permissions);
}
// String username =(String) getAvailablePrincipal(principals);
// //系统角色
// Set<String> roles=new HashSet<>();
// roles.add("超级管理员");
// //角色所用户的权限
// Set<String> permissions=new HashSet<>();
// //这里定义了一个list的权限,这个可以不一定要这样写,只要跟后面再controller中的注解一致即可
// permissions.add("admin:shiro:list");
// //为当前用户添加角色和权限
// SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
// info.setRoles(roles);
// info.setStringPermissions(permissions);
return info;
}
doGetAuthenticationInfo:该方法用于校验当前登录请求的账号和密码是否正确;
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//方法1:获取登陆人账号
String name = token.getPrincipal().toString();
//这里强转的类型不一定要是UsernamePasswordToken ,具体要看你在登录接口中所传的对象类型
//方法2:获取登陆人账号
UsernamePasswordToken usernamePasswordToken= (UsernamePasswordToken)token;
String username = usernamePasswordToken.getUsername();
//判断内容是否为空
User user=userService.selectByUserName(username);
if(user==null){
throw new AccountException("用户名不能为空");
}
//这里有三个参数,第一个是账号,第二个是密码,第三个是用户名
//这里的密码需要传递用户的正确密码,这样shiro才能帮我们做校验
SimpleAuthenticationInfo simpleAuthenticationInfo=new SimpleAuthenticationInfo(username,user.getUpwd(),getName());
return simpleAuthenticationInfo;
}
3:将我们自定义的realm和securityManager加入到spring容器中
import com.example.realm.LoginAuthorizingRealm;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.Realm;
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 java.util.LinkedHashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
//配置realm
@Bean
public Realm realm(){
return new LoginAuthorizingRealm();
}
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
//过滤器规则
Map<String,String> filterChainDefinitionMap=new LinkedHashMap<>();
filterChainDefinitionMap.put("/admin/login","anon");
filterChainDefinitionMap.put("/admin/unAuth","anon");
filterChainDefinitionMap.put("/admin/401","anon");
filterChainDefinitionMap.put("/**","authc");
//这里定义用户未认证时跳转的路径
shiroFilterFactoryBean.setLoginUrl("/admin/401");
//这里是用户登录成功后跳转的路径
shiroFilterFactoryBean.setSuccessUrl("/admin/index");
//这里是用户没有访问权限跳转的路径
shiroFilterFactoryBean.setUnauthorizedUrl("/admin/unAuth");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
// 将realm加入管理器中
@Bean(name="securityManager")
public DefaultWebSecurityManager defaultWebSecurityManager(){
DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(realm());
return defaultWebSecurityManager;
}
}
package com.example.controller;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("admin/")
public class ShiroController {
@RequestMapping("login")
public String login(String username, String password) {
//获取主体
Subject subject = SecurityUtils.getSubject();
try {
subject.login(new UsernamePasswordToken(username, password));
} catch (UnknownAccountException e) {
return "账号不存在";
} catch (AccountException e) {
return "账号或密码不正确";
} catch (IncorrectCredentialsException e) {
return "账号或密码不正确";
}
return "登陆成功";
}
@RequestMapping("401")
public String toLogin() {
return "401页面,您先去登陆吧!";
}
@RequestMapping("index")
public String index() {
return "index主页";
}
@RequiresPermissions("book:list")
@RequestMapping("list")
public String list() {
return "book:list";
}
@RequiresPermissions("book:add")
@RequestMapping("add")
public String add() {
return "book:add";
}
@RequiresPermissions("book:update")
@RequestMapping("update")
public String update() {
return "book:update";
}
@RequiresPermissions("book:delete")
@RequestMapping("delete")
public String delete() {
return "book:delete";
}
@RequiresPermissions("user:list")
@RequestMapping("ulist")
public String ulist() {
return "user:list";
}
@RequiresPermissions("user:add")
@RequestMapping("uadd")
public String uadd() {
return "user:add";
}
@RequestMapping("unAuth")
public String unAuth() {
return "未认证";
}
}
5新增exception,对于报AuthorizationException异常进行处理
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;
@ControllerAdvice
public class ShiroExceptionHandle {
@ExceptionHandler(AuthorizationException.class)
@ResponseBody
public String unAuth(AuthorizationException e){
return "noAuth:"+e.getMessage();
}
}