1、首先加上maven依赖的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>
在以前spring集成shiro的时候,会在web.xml和spring.xml中配置很多文件,在springboot中没有xml文件,所以通过@bean的方式来配置
2.编写一个配置类
package cn.et.demo03.config;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.DelegatingFilterProxy;
@Configuration
public class ShiRoConfig {
/**
等价于 web.xml配置
<filter>
<filter-name>shiRoFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiRoFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
* @return
*/
@Bean
public FilterRegistrationBean webShiRoFilter(){
FilterRegistrationBean frb=new FilterRegistrationBean();
DelegatingFilterProxy dfp=new DelegatingFilterProxy();
frb.setFilter(dfp);
frb.setName("shiRoFilter");
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<String>();
linkedHashSet.add("/*");
frb.setUrlPatterns(linkedHashSet);
Map<String, String> initParameters=new HashMap<String, String>();
initParameters.put("targetFilterLifecycle", "true");
frb.setInitParameters(initParameters);
return frb;
}
/**
* 配置我的realm
* @return
*/
@Bean
public Realm myRealm(){
return new MyRealm();
}
/**
* 定义默认的securityManager
* @return
*/
@Bean
public DefaultWebSecurityManager securityManager(@Autowired Realm myRealm){
DefaultWebSecurityManager dwm=new DefaultWebSecurityManager();
dwm.setRealm(myRealm);
return dwm;
}
/**
* 定义和过滤器一致名字的shiRoFilterFactoryBean
*/
@Bean
public ShiroFilterFactoryBean shiRoFilter(@Autowired SecurityManager securityManager){
ShiroFilterFactoryBean filterFactoryBean=new ShiroFilterFactoryBean();
filterFactoryBean.setSecurityManager(securityManager);
// 如果需要授权就跳转到这个路径
filterFactoryBean.setLoginUrl("/Login.jsp");
// 如果没有权限就跳转到这个路径
filterFactoryBean.setUnauthorizedUrl("/RoleError.jsp");
// 自定义一个过滤器
Map<String, String> urls=new HashMap<String, String>();
urls.put("/**", "myFilter");
// urls.put("/Login.jsp", "anon");
// urls.put("/LoginSuccess.jsp", "authc");
filterFactoryBean.setFilterChainDefinitionMap(urls);
return filterFactoryBean;
}
/**
* 定义ShiRo的生命周期
* @return
*/
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
return new LifecycleBeanPostProcessor();
}
}
一般情况下,我们用shiro都会自己去实现Realm和过滤器来控制权限
3.实现Realm
package cn.et.demo03.config;
import cn.et.demo03.mapper.UserMapper;
import cn.et.demo03.model.UserInfoModel;
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 org.springframework.stereotype.Component;
import java.util.Set;
@Component
public class MyRealm extends AuthorizingRealm {
@Autowired
private UserMapper userInfoMapper;
/**
* 获取当前用户的权限
* 将当前用户在数据库的角色的权限 加载到AuthorizationInfo
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String userName =principals.getPrimaryPrincipal().toString();
Set<String> roleList =userInfoMapper.getRoleByUserName(userName);
//角色集合对象
SimpleAuthorizationInfo sai =new SimpleAuthorizationInfo();
sai.setRoles(roleList);
return sai;
}
/**
* 认证
* 将登陆输入的用户名和密码跟数据库里面的用户名密码对比 是否相等
* 返回值 null表示认证失败 非null认证通过
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//页面传入的token
UsernamePasswordToken upt =(UsernamePasswordToken)token;
UserInfoModel queryUser =userInfoMapper.getUserByUserName(token.getPrincipal().toString());
if (queryUser !=null && queryUser.getPassword().equals(new String(upt.getPassword()))) {
SimpleAccount sa =new SimpleAccount(upt.getUsername(),upt.getPassword(),"MyDbRealm");
return sa;
}
return null;
}
}
4.实现过滤器
package cn.et.demo03.config;
import cn.et.demo03.mapper.MenuMapper;
import cn.et.demo03.model.MenuModel;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
@Component
public class MyFilter extends AuthorizationFilter {
@Autowired
private MenuMapper menuMapper;
/**
* 匹配指定过滤器规则的url
* @param regex
* @param url
* @return
*/
public static boolean matchUrl(String regex,String url){
regex=regex.replaceAll("/+", "/");
if(regex.equals(url)){
return true;
}
regex=regex.replaceAll("\\.", "\\\\.");
// /login.html /l*.html
regex=regex.replaceAll("\\*", ".*");
// /**/login.html /a/b/login.html
if(regex.indexOf("/.*.*/")>=0){
regex=regex.replaceAll("/\\.\\*\\.\\*/", "((/.*/)+|/)");
}
System.out.println(regex+"----"+url);
return Pattern.matches(regex, url);
}
/**
* isAccessAllowed用于判断当前url的请求是否能验证通过 如果验证失败 调用父类的onAccessDenied决定跳转到登录失败页还是授权失败页面
*/
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)throws Exception {
HttpServletRequest req=(HttpServletRequest)request;
//获取用户访问的资源路径
String url=req.getRequestURI();
//获取哪些url需要哪些认证
List<MenuModel> list = menuMapper.getMenuByUrl(url);
//数据库没有配置当前url的授权
if (list.size()==0) {
return false;
}
String urlAuth=null;
for (MenuModel menu : list) {
if (matchUrl(menu.getUrl(), url)) {
urlAuth =menu.getFilter();
}
}
if(urlAuth==null){
return false;
}
//配置的过滤器是anon 直接放过
if(urlAuth.startsWith("anon")){
return true;
}
//配置的是authc 判断当前用户是否认证通过
Subject subject = getSubject(request, response);
if(urlAuth.startsWith("authc")){
return subject.isAuthenticated();
}
//授权认证 也需要判断是否登录 没有登录返回 登录继续下面的验证
boolean ifAuthc=subject.isAuthenticated();
if(!ifAuthc){
return ifAuthc;
}
//如果是定义的roles过滤器 获取所有的roles 一般是roles[a,b]
if(urlAuth.startsWith("roles")){
String[] rolesArray=urlAuth.split("roles\\[")[1].split("\\]")[0].split(",");
if (rolesArray == null || rolesArray.length == 0) {
return true;
}
Set<String> roles = CollectionUtils.asSet(rolesArray);
return subject.hasAllRoles(roles);
}
if(urlAuth.startsWith("perms")){
String[] perms=urlAuth.split("perms\\[")[1].split("\\]")[0].split(",");
boolean isPermitted = true;
if (perms != null && perms.length > 0) {
if (perms.length == 1) {
if (!subject.isPermitted(perms[0])) {
isPermitted = false;
}
} else {
if (!subject.isPermittedAll(perms)) {
isPermitted = false;
}
}
}
return isPermitted;
}
return false;
}
}
5.编写一个测试类
package cn.et.demo03.controller;
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.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("demo03")
public class ShiRoController {
@RequestMapping("login")
public String login(String userName, String password){
//获取当前的用户
Subject currentUser =SecurityUtils.getSubject();
//用户输入的用户名跟密码
UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
try {
currentUser.login( token );
return "/LoginSuccess.jsp";
} catch (UnknownAccountException uae) {
System.out.println("用户名不存在:" + token.getPrincipal());
} catch (IncorrectCredentialsException ice) {
System.out.println("密码不正确!!");
} catch (LockedAccountException lae) {
System.out.println("用户已被锁定!!");
}
return "/LoginError.jsp";
}
}
6.添加一个springboot启动类
package cn.et;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//必须添加 @SpringBootApplication 启动spring的自动配置功能 必须要添加
@SpringBootApplication
//扫描mapper包 一般用于全局 (推荐使用) 或许在每个类上面加 @Mapper注解效果等价
@MapperScan("cn.et.**.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
以上就是在springboot使用shiro控制权限的核心代码。。。。。。。。