本Demo是用SpringBoot+Mybatis+Shiro
省略创建SpringBoot的截图流程
导入jar包
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
整个项目结构
shiro一般都在service(业务层)内
CredentialMatcher类是自定义登陆验证规则
AuthRealm类是每次登陆授权时需要使用的类
shiroConfiguration类是shiro的总配置文件
从大到小的顺序是 shiroConfiguration→AuthRealm→CredentialMatcher
CredentialMatcher
package com.hjy.serivce;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
/**
* 自定义登陆检验规则
*/
public class CredentialMatcher extends SimpleCredentialsMatcher {
//自定义验证规则
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
UsernamePasswordToken usernamePasswordToken=(UsernamePasswordToken) token;
//session的密码
String password =new String(usernamePasswordToken.getPassword());
//数据库对应的密码
String dePassword=info.getCredentials().toString();
//返回对比结果
return this.equals(password,dePassword);
}
}
AuthRealm
PS:我的dao和service只写一个方法就是通过传用户名来查找对应用户角色权限信息
package com.hjy.serivce;
import com.hjy.entity.Permission;
import com.hjy.entity.Role;
import com.hjy.entity.Users;
import org.apache.commons.collections.CollectionUtils;
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.ArrayList;
import java.util.List;
import java.util.Set;
/**
* 验证授权类
*/
public class AuthRealm extends AuthorizingRealm {
@Autowired(required = false)
private UsersService usersService;
//授权(每次验证权限或角色都会走这个方法)
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//从session里面获取当前用户
Users users=(Users) principalCollection.fromRealm(this.getClass().getName()).iterator().next();
//存放给info添加所有关系集合
List<String> permissionList=new ArrayList<>();
//所有角色集合
Set<Role> roleSet=users.getRoles();
//存放给info添加的角色集合
List<String> roleNameList=new ArrayList<>();
//判断角色是否为空
if (CollectionUtils.isNotEmpty(roleSet)){
for (Role role : roleSet){
//获取所有角色信息后添加进集合(存放到info)
roleNameList.add(role.getRname());
//获取所有关系集合
Set<Permission> permissionSet=role.getPermissions();
if (org.apache.commons.collections.CollectionUtils.isNotEmpty(permissionSet)){
for (Permission permission:permissionSet){
//获取所有权限后添加进集合
permissionList.add(permission.getName());
}
}
}
}
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
info.addStringPermissions(permissionList);
info.addRoles(roleNameList);
System.out.println("授权");
return info;
}
//认证登陆
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken usernamePasswordToken=(UsernamePasswordToken) authenticationToken;
String username=usernamePasswordToken.getUsername();
Users users=usersService.findByUsersName(username);
System.out.println("登陆");
return new SimpleAuthenticationInfo(users,users.getPassword(),this.getClass().getName());
}
public UsersService getUsersService() {
return usersService;
}
public void setUsersService(UsersService usersService) {
this.usersService = usersService;
}
}
shiroConfiguration
package com.hjy.serivce;
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.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.LinkedHashMap;
/**
* shiro配置整合
* 最下面是底层,依次向上
*/
@Configuration
public class ShiroConfiguration {
//把SecurityManager放入Filter过滤内,并配置过滤规则
@Bean("shiroFilterFactoryBean")
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") SecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
//注销后跳转的页面
shiroFilterFactoryBean.setLoginUrl("/login");
//登陆成功后跳转的页面
shiroFilterFactoryBean.setSuccessUrl("/index");
//
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
//配置过滤规则(过滤规则搜索DefaultFilter,apache的)
LinkedHashMap<String,String> filterChainDefinitionMap=new LinkedHashMap<>();
filterChainDefinitionMap.put("/index","authc");
filterChainDefinitionMap.put("/login","anon");
filterChainDefinitionMap.put("/loginUser","anon");
//下面这个只是允许admin角色用户访问
filterChainDefinitionMap.put("/admin","roles[admin]");
//只允许拥有该权限的人才能访问
filterChainDefinitionMap.put("/edit","perms[edit]");
filterChainDefinitionMap.put("/**","user");
//把规则添加到shiroFilter内
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
//把authRealm放入SecurityManager里面
@Bean("securityManager")
public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm){
DefaultWebSecurityManager manager=new DefaultWebSecurityManager();
manager.setRealm(authRealm);
return manager;
}
//把自定义规则通过参数从Spring里面拿出来用
@Bean("authRealm")
public AuthRealm authRealm(@Qualifier("credentialMatcher")CredentialMatcher credentialMatcher){
AuthRealm authRealm=new AuthRealm();
//把自定义规则发放如Realm内
authRealm.setCredentialsMatcher(credentialMatcher);
return authRealm;
}
//前面的自定义规则(这是一个类)
@Bean("credentialMatcher")
public CredentialMatcher credentialMatcher(){
return new CredentialMatcher();
}
//下面两个是关联配置
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager){
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor=new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator();
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
return defaultAdvisorAutoProxyCreator;
}
}
Controller层
package com.hjy.controller;
import com.hjy.entity.Users;
import com.hjy.serivce.UsersServiceImpl;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
@Controller
public class UsersController {
@Resource
private UsersServiceImpl usersService;
public UsersServiceImpl getUsersService() {
return usersService;
}
public void setUsersService(UsersServiceImpl usersService) {
this.usersService = usersService;
}
/* @RequestMapping("/text")
public String text(){
return JSONArray.toJSONString(usersService.findByUsersName("admin"));
}*/
@RequestMapping("/login")
public String login(){
return "login";
}
@RequestMapping("/index")
public String index(){
return "index";
}
@RequestMapping("/logout")
public String logout(){
Subject subject=SecurityUtils.getSubject();
if (subject!=null){
subject.logout();
}
return "redirect:/login";
}
@GetMapping
@ResponseBody
public String admin(){
return "只有admin才能看到的";
}
//登陆认证
@RequestMapping("/loginUser")
public String loginUsers(@RequestParam("username")String username,
@RequestParam("password")String password,
HttpServletRequest request){
//传入用户名和密码进去
UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken(username,password);
Subject subject=SecurityUtils.getSubject();
try {
//开始认证,若出错则会catch
subject.login(usernamePasswordToken);
//获得对象
Users users=(Users) subject.getPrincipal();
//把对象放入session内
request.getSession().setAttribute("users",users);
//成功则返回index页面
return "redirect:/index";
} catch (Exception e) {
//失败则返回到login页面
return "redirect:/login";
}
}
@GetMapping("/edit")
@ResponseBody
public String edit(){
return "edit返回信息";
}
@GetMapping("unauthorized")
public String unauthorized(){
return "unauthorized";
}
}
这是本次Demo的码云下载地址https://gitee.com/chijj/shiroDemo1.git