要将shiro与web集成必须要添加shiro-spring依赖:
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>配置shiro
import org.apache.shiro.mgt.DefaultSecurityManager;
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.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 结合spring,shiro完成web的认证和授权
*/
@Configuration
public class ShiroConfig {
@Bean
public DefaultSecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(definedRealm());
return securityManager;
}
@Bean
public DefinedRealm definedRealm(){
DefinedRealm realm = new DefinedRealm();
return realm;
}
@Bean
public ShiroFilterFactoryBean shiroFilter(){
ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
shiroFilter.setSecurityManager(securityManager());
shiroFilter.setLoginUrl("/login");//设置登录URL
shiroFilter.setUnauthorizedUrl("/403");//设置未授权URL
shiroFilter.setSuccessUrl("/index");//设置登录成功后跳转URL
//设置拦截的路径
Map<String,String> filterChain = new LinkedHashMap<>();
filterChain.put("/logout","logout");
filterChain.put("/css/**","anon");
filterChain.put("/fonts/**","anon");
filterChain.put("/images/**","anon");
filterChain.put("/js/**","anon");
filterChain.put("/login","anon");
filterChain.put("/list","roles[frame]");
filterChain.put("/**","authc");//设置在最后,按照顺序判断,如果匹配则返回
shiroFilter.setFilterChainDefinitionMap(filterChain);
return shiroFilter;
}
}登录控制器:
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.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class LoginController {
@RequestMapping(value = "/login",method = RequestMethod.GET)
public String login(){
System.out.println("首页登录");
return "login";
}
@RequestMapping(value = "/login",method = RequestMethod.POST)
public String login(String username,String password){
System.out.println("开始验证登录信息,username " + username );
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","123");
try {
subject.login(token);
return "index";
}catch (Exception e){
e.printStackTrace();
}
return "login";
}
@RequestMapping("/index")
public String index(){
System.out.println("登录成功");
return "index";
}
@RequestMapping("/403")
public String error(){
System.out.println("请先登录");
return "403";
}
}以上简单实现了shiro和web的集成。集合以上shiro配置代码和POST请求方式的login()方法,与上一节的登录控制器比较,发现其实我们只是将realm和securityManager的Bean交个spring容器来管理。
上一节登录控制器如下:
DefaultSecurityManager securityManager = new DefaultSecurityManager();
//设置realm
securityManager.setRealm(definedRealm);
//绑定securityManager到securityUtils
SecurityUtils.setSecurityManager(securityManager);
//创建登录实体
Subject subject = SecurityUtils.getSubject();
//创建登录token
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","01d7f40760960e7bd9443513f22ab9af");
//登录
subject.login(token);并且再配置ShiroFilterFactoryBean。通过该类来配置我们loginUrl、UnauthorizedUrl、SuccessUrl,以及用户访问时需要认证和鉴权的URL。
配置URL的规则
配置URL通配符的规则:
- ?、*、**,注意通配符匹配不包括目录分隔符“/”:
- ?:匹配一个字符,如 /admin? 将匹配 /admin1,但不匹配 /admin 或 /admin/;
- *:匹配零个或多个字符串,如 /admin* 将匹配 /admin、/admin123,但不匹配 /admin/1;
- **:匹配路径中的零个或多个路径,如 /admin/** 将匹配 /admin/a 或 /admin/a/b
后面的选项只能在下面的 表格中选择:
首先是认证相关,当我们配置认证相关过滤器时,如果没有认证通过将会跳转到我们配置的loginUrl。常用authc过滤器

其次是授权相关的,当我们配置如下过滤器,鉴权没通过是,将会跳转到配置的UnauthorizedUrl。一般很少使用,因为使用注解会更方便

上面提到了注解做鉴权,下面来看看如何使用shiro的注解鉴权。
shiro中注解的使用
首先是启用shiro-spring的aop,在shiro配置类中增加如下配置:
/**
* Spring的一个bean,有advisor决定对那些类实现AOP代理
* 配置通过注解完成权限和角色验证
* @return
*/
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
DefaultAdvisorAutoProxyCreator defaultAdvisor = new DefaultAdvisorAutoProxyCreator();
defaultAdvisor.setProxyTargetClass(true);
return defaultAdvisor;
}
/**
* shiro类的实现Advisor的类,开启shiro的注解支持
* 内部使用AopAllianceAnnotationsAuthorizingMethodInterceptor
* 拦截@RequiredRoles,@RequiredPermission注解的方法
* @return
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(){
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager());
return advisor;
}
/**
* shiro生命周期处理器
* @return
*/
@Bean(name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}在loginController中增加如下接口:
@RequiresRoles("admin")
@RequestMapping("list")
public String list(){
return "list";
}当我们登录成功后,再去访问该接口时,如果当前登录用户没有该角色将会抛出org.apache.shiro.authz.AuthorizationException异常。
以上就是shiro和web的初步结合,下一节来探讨shiro中会话管理
本文介绍了如何将Apache Shiro安全框架与Web应用进行集成,包括添加shiro-spring依赖,配置shiro,设置URL规则,以及使用shiro的注解进行权限管理。详细讲述了登录控制器的实现,URL通配符的规则,以及如何启用注解鉴权。
374

被折叠的 条评论
为什么被折叠?



