shiro学习,可去bilibili
上面,有许多教学视频。另外还有《跟我学Shiro》
这个系列也不错,但得有点shiro基础,不然想看文字入门还是很难的
今天,简单做了一下shiro的demo:主要有以下几个步骤(结合springmvc)
- 搭起springmvc框架,
- 在web.xml进行shiro的相关配置
- 编写shiro.xml
- 编写自定义Realm, 和登录Controller
- 在jsp页面引入相应shiro标签。
1.忽略。。。。
2.web.xml的shiro配置:
2. 1、初始化shiro的xml
<!--1.配置监听器,加载spring配置 和Shiro-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml,classpath:shiro.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
2.2、配置shiro过滤器
<filter>
<filter-name>shiro</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>shiro</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
---这一部分,基本差不多
3.编写shiro.xml :这里,写的是一个精简版的。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--shiro的配置-->
<!--1.shiro过滤器的配置-->
<!--这个要和web.xml中的shiro过滤器名字一样-->
<bean id="shiro" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securitymanager"/>
<property name="loginUrl" value="/slogin"/>
<!--路径配置,可以直接在这里写,但打包后修改不方便,这种方法好处是,路径信息能写进数据库,方便修改-->
<property name="filterChainDefinitionMap" ref="filterurlmap" />
</bean>
<!--获取路径配置的map-->
<!--1.获取map工厂-->
<bean id="filterurlmapfactory" class="jshiro.shiroFilterMap"/>
<!--2.从工厂获取map-->
<bean id="filterurlmap" factory-bean="filterurlmapfactory" factory-method="shiroFilterMapFactory" />
<!--获取路径配置的map-->
<!--2.注入自定义Realm,
Realm如何工作:分为两块:验证块 和 授权块
验证块先执行,作用是:看你的账号密码对不对
1.获取你输入的账号,
2.拿你的账号,去数据库查,出相应的密码,交给:SimpleAuthenticationInfo,它会把查出来的和你输入的进行比对!
3.返回比对结果
授权块,作用是:现在比登录了,从你登录的角色中获取账号去数据库查,你有那些身份,是管理员,还是vip,,等
,然后,在去查管理员等身份有那些权利。告诉SimpleAuthorizationInfo,它把你的身份,权利信息管理起来。
1.从登录角色中获取账号
2.用账号去查你的身份
3.写进shiro去
4.查身份的权利(如果有的话)
5.写进去
6.返回
-->
<bean id="jrealm" class="jshiro.jRealm"/>
<!--3.配置SecrityManager,-->
<bean id="securitymanager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="jrealm"/>
</bean>
<!--4.其他,比如自定义缓存管理,remrember me配置-->
</beans>
4.配置自定义Realm和路径的map
4.1自定义Realm:我这里为了简便没建表,模拟查询
package jshiro;
import jObject.juser;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.Permission;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.subject.PrincipalCollection;
import java.util.HashSet;
import java.util.Set;
/**
* @author :JXH
* @time :2019-02-21-下午6:22
*/
public class jRealm extends AuthorizingRealm {
/*
账号,密码 验证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken usernamePasswordToken=(UsernamePasswordToken)authenticationToken;
String username=usernamePasswordToken.getUsername();
System.out.println("用户输入的账号:"+username);
//根据用户名,去数据库查询出密码,把它给shiro,让它进行比对
juser juser = new juser(1,username,"123");//模拟数据库获取
// System.out.println("getName():"+getName());
System.out.println("-------我是验证1---------");
System.out.println("is_remember:"+((UsernamePasswordToken) authenticationToken).isRememberMe());
return new SimpleAuthenticationInfo(juser,// 以后这个对象就保存了你登录的信息
juser.getPassword(),//从数据库查出的密码
getName());
}
/*
对登录输入的账号,进行 身份授权。,把该用户的权限告诉shiro,交给他管理!
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
// String username=(String)principalCollection.fromRealm(getName()).iterator().next();
System.out.println("----------我是授权2----------");
juser juser=(juser) principalCollection.getPrimaryPrincipal();
String username=juser.getUsername();
// 根据用户输入的账号,进数据库查询,他的角色,并交给shiro
Set<String> set=new HashSet<>();
// 模拟数据库查询,如果你输入了账号anon,就给你普通用户的身份!
if (username.equals("anon")){ //为了测试
set.add("anon");//普通用户
}
if (username.equals("admin")){
set.add("admin");//普通管理员
}
if (username.equals("superadmin")){
set.add("superadmin");
}
//权限信息对象 info
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
//把角色添加进去。
info.setRoles(set);
//查询不同角色的权限
for (String s:set){
// 本来角色的权利是存在数据库的,在这就不建表了。用角色,去数据库查相应的权利
if(s.equals("anon")){
info.addStringPermission("view");//我们就在这,假设anon,具有 view能力
}
if(s.equals("admin")){
info.addStringPermission("write");//我们就在这,假设admin,具有 write能力
}
if(s.equals("superadmin")){
info.addStringPermission("delete");//我们就在这,假设superadmin,具有 delete能力
}
}
return info;//返回角色对象
}
}
4.2 路径map
package jshiro;
import java.util.LinkedHashMap;
/**
* @author :JXH
* @time :2019-02-21-下午6:07
*/
public class shiroFilterMap {
public LinkedHashMap<String,String> shiroFilterMapFactory(){
LinkedHashMap<String,String> map=new LinkedHashMap<>();
//此处从数据库获取
//显示登录页面
map.put("/slogin","anon");
//提交登录路径
map.put("/login","anon");
map.put("/**","authc");
return map;
}
}
4.3登录Controller
@RequestMapping("login")
public String login(String username,String password){
UsernamePasswordToken token=new UsernamePasswordToken(username,password);
// 假设用户,进行了 remember me操作!
token.setRememberMe(true);
try {
SecurityUtils.getSubject().login(token);
}catch (AuthenticationException e){
e.getStackTrace();
return "slogin";//账号密码不匹配处理
}
return "show";
}
5. jsp 中使用shiro标签
<%--
Created by IntelliJ IDEA.
User: jxh
Date: 19-2-21
Time: 下午8:19
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<html>
<head>
<title>Title</title>
</head>
<body>
shiro标签<br>
<shiro:notAuthenticated>
<p>不登录,才能看到的提示!shiro:notAuthenticated</p>
</shiro:notAuthenticated>
(shiro:principal property="属性")当前用户账号:
<shiro:principal property="username"></shiro:principal><br>
<shiro:authenticated>
<p>这条信息登录就能看到!shiro:authenticated</p>
</shiro:authenticated>
<shiro:guest>
不登录也能看到!
</shiro:guest>
<shiro:hasAnyRoles name="admin,superadmin">
<p>只有管理员,或超级管理员才能看到 shiro:hasAnyRoles name="admin.superadmin"</p>
</shiro:hasAnyRoles>
<shiro:hasPermission name="write">
<p>具有write权利,才能看到! shiro:hasPermission name="write"</p>
</shiro:hasPermission>
<shiro:lacksPermission name="view">
<p>抱歉你不是anon,没有view权利!</p>
</shiro:lacksPermission>
<shiro:user>
你已经进行了身份验证,或remrember me,操作!
</shiro:user>
</body>
</html>
shiro还有一些注解:
1.先开启shiro注解:
<aop:config proxy-target-class="true"></aop:config>
<bean class="
org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
2.接着就可以在相应的控制器Controller中使用如下方式进行注解
- @RequiresRoles("admin") =======>当前用户有admin角色,才能进这个方法
- @RequiresAuthentication 当前Subject已经通过login进行了身份验证
- @RequiresUser 当前Subject已经身份验证或者通过记住我登录的
- @RequiresGuest 游客身份
- @RequiresRoles(value={“admin”, “user”}, logical= Logical.AND) 当前Subject需要角色admin和user
项目路径: