一.在web项目中实现认证
第一步,在web项目中导入shiro依赖的包
第二步,在web.xml中声明shiro拦截权限的过滤器
<filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param> <!--保证该过滤器的生命周期和spring 工厂中shiro过滤器对象的生命周期一致--> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> <!--声明该过滤器代理工厂类中的id为什么的shiro过滤器对象--> <init-param> <param-name>targetBeanName</param-name> <param-value>shiroFilter</param-value> </init-param> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
第三步,在spring的主配置文件中声明shiro的配置信息
shiro的配置信息比较多,一般不和spring的主配置文件放到一起。一般都会单独建立一个shiro和spring集成的配置文件。
创建好该文件后,要在spring.xml中引入该文件:
在spring中自定义域对象:
/** * 实现自定义域 * Authorization 授权(权限校验) * * Authentication 认证(登录校验) * */ public class AuthRealm extends AuthorizingRealm { @Autowired private UserService userService; //获取授权信息 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { return null; } //获取认证信息 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { //获取用户名 不过一般往shiro中放置用户身份信息的时候,不直接放用户名字符串,放用户对象 String username = token.getPrincipal().toString(); //有了用户名,要根据用户名在数据库中查询用户对象 Users user = userService.findByUsername(username); //判断如果用户对象不存在,抛出UnknownAccountException if(user==null){ throw new UnknownAccountException("用户名不存在"); } //封装用户的身份对象 返回这个身份对象 SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),"authRealm"); return info; } }
在shiro的主配置文件spring-shiro.xml中做配置:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--创建自定义域对象--> <bean id="authRealm" class="com.aaa.ssm.realm.AuthRealm"></bean> <!--创建shiro的安全管理器对象--> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <!--要声明域,在域中读取认证和授权的数据--> <property name="realm" ref="authRealm"></property> </bean> <!--创建shiro的过滤器对象--> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!--要注入安全管理器对象--> <property name="securityManager" ref="securityManager"></property> <!--配置登录请求的路径--> <property name="loginUrl" value="/user/login.do"></property> <!--配置shiro认证和授权的过滤器--> <property name="filterChainDefinitions"> <value> <!--对静态资源不拦截--> <!--anon指匿名访问的过滤器,所有匿名用户都可以访问static下面的资源--> /static/*=anon /user/login.do=anon /login.jsp=anon <!--authc指必须经过认证(登录过之后)才能访问的请求 /*代表所有有一个斜杠的请求都要经过认证 --> /*=authc /*/*=authc </value> </property> </bean> </beans>
第四步,在控制器中使用shiro去做登录认证
/** * 用户登录的请求 * @param user * @return */ @RequestMapping("/login") public String login(Users user, Model model, HttpSession session){ //获取用户的主体对象 Subject subject = SecurityUtils.getSubject(); //封装用户名和密码的认证信息对象 UsernamePasswordToken upt = new UsernamePasswordToken(user.getUsername(),user.getPassword()); //进行登录认证 try { subject.login(upt); }catch (Exception e){ e.printStackTrace(); System.out.println("用户名或者密码错误"); return "redirect:/login.jsp"; } return "index"; }
二.在web项目中实现授权
当前我们还没有配置授权的信息,所以用户登录成功之后能访问所有的请求。
配置文件的方式
xml的方式
第一步,在shiro的主配置文件中配置授权信息
第二步,当前登录用户有哪些授权信息从自定义的realm中读取
注解的方式
第一步,开始spring的shiro的注解的支持
注意,开启注解的支持之前,应该保证项目中有spring 的aop的jar包的,aspectj等的jar包。
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <!-- aspectj相关jar包--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.7.4</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.7.4</version> </dependency>
要在spring mvc的主配置文件中声明shiro的注解的支持:
第二步,在控制器的代码中增加需要授权的注解
第三步,同xml的方式的第二步
第四步,声明spring mvc的统一异常处理
因为如果用户没有权限,会跳转到500界面,不友好,我们可以使用spring mvc统一异常处理机制,让用户跳转到一个统一的界面。