Shiro学习记录
Shiro主要功能:身份验证;授权;会话管理;密码 IDEA中 ctrl+ alt+ v可自动生成对应变量及对应的数据类型 IDEA中 ctrl+ alt+ t可自动提示一些可用的,例如try catch,if else等
1.介绍
导包一定是:import org.apache.shiro
或其之下更进一步详细的包,不要导成别的包,例如java.lang
的,否则会报错
初始项目:实现登陆判断(身份验证):以下代码均在main方法中
//假设路径中能够获得用户名和密码
Factory<SecurityManager> factory = new IniSecurityManagerFactory("路径");
SecurityManager securityManager = factory.getInstance();
//当前用户:Subject————>SecurityUtils
SecurityUtils.setSecurityManager(securityManager);
//当前用户
Subject user = SecurityUtils.getSubject();
//通过UsernamePasswordToken来模拟html/jsp传递过来的用户名和密码
UsernamePasswordToken token = new UsernamePasswordToken("用户名","密码");
//通过shiro判断用户是否登录成功
//login是void类型方法,通过抛出异常来判断
try{
user.login(token);//login是shiro自带的
System.out.println("登陆成功");
}catch(AuthenticationException e){
System.out.println("登陆失败");
}
2.jdbcRealm工具类(身份验证)
通过数据库实现登陆判断(身份验证):
java的main方法中:
//假设路径中能够获得用户名和密码
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:jdbc_shiro.ini");
SecurityManager securityManager = factory.getInstance();
//当前用户:Subject————>SecurityUtils
SecurityUtils.setSecurityManager(securityManager);
//当前用户
Subject user = SecurityUtils.getSubject();
//通过UsernamePasswordToken来模拟html/jsp传递过来的用户名和密码
UsernamePasswordToken token = new UsernamePasswordToken("用户名","密码");
//通过shiro判断用户是否登录成功
//login是void类型方法,通过抛出异常来判断
try{
user.login(token);//login是shiro自带的
System.out.println("登陆成功");
}catch(AuthenticationException e){
System.out.println("登陆失败");
}
jdbc_shiro.ini(在resources目录下)文件中:
jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
//数据库c3p0连接池
dataSource=com.mchange.v2.c3p0.ComboPooledDataSource
dataSource.driverClass=com.mysql.jdbc.Driver
dataSource.jdbcUrl=jdbc:mysql://localhost:3306/news?useUnicode=true&characterEncoding=utf-8
dataSource.user="rout"
dataSource.password="123456"
jdbcRealm.dataSource=$dataSource
securityManager.realm=$jdbcRealm
3.SSM整合(认证加授权)
3.1.pom.xml文件添加相关依赖
<!-- shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
3.2.web.xml文件添加过滤器
<!-- shiro过滤器 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.3.jsp文件添加说明
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
配合
<shiro:guest><!--未认证时就显示-->
登录
</shiro:guest>
<shiro:authenticated><!--认证后才显示-->
退出登录
</shiro:authenticated>
使用
3.3.applicationContext.xml文件添加控制
<bean id="myRealm" class="com.shiro.myRealm" />
<!--配置安全管理器-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!--关联一个认证授权域-->
<property name="realm" ref="myRealm"/>
</bean>
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!--必须配置-->
<property name="securityManager" ref="securityManager"/>
<!--配置登录页面-->
<property name="loginUrl" value="/login.jsp"/>
<!--认证成功后-->
<property name="successUrl" value="/pages/homepage.jsp"/>
<!--未授权-->
<property name="unauthorizedUrl" value="/pages/403.jsp"/>
<!--过滤器规则-->
<property name="filterChainDefinitions">
<value>
/index.jsp = anon <!--匿名-->
/readerpost.jsp = anon
/login.jsp = anon
/pages/** = authc<!--必须认证-->
</value>
</property>
</bean>
3.4.修改Controller层中login()内代码
@RequestMapping("/login.do")
@ResponseBody
public String login(String userid, String password, HttpSession session){
//得到一个主题对象
Subject subject = SecurityUtils.getSubject();
//创建一个token
UsernamePasswordToken token = new UsernamePasswordToken(userid,password);
try{
//传令牌
subject.login(token);
if(subject.isAuthenticated()){
int id=Integer.parseInt(userid);
Admin admin= new Admin();
admin=adminService.findAdminByAdminId(id);
session.setAttribute("adminid",admin.getId());
Gson json=new Gson();
String str=json.toJson(admin);// 传入Bean类型
System.out.println(str);
return str;
}else{
return null;
}
}catch (AuthenticationException ex){
return null;
}
}
主要是画框的部分
3.5.在myRealm中
public class myRealm extends AuthorizingRealm {
@Autowired
private AdminService adminService;
//获取授权信息:进行授权工作
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
//获取认证信息:进行认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
String username = token.getUsername();
char[] password = token.getPassword();
int id=Integer.parseInt(username);
boolean admin = adminService.login(id,String.valueOf(password));
System.out.println(admin);
System.out.println(username);
System.out.println(String.valueOf(password));
if(admin){
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username,String.valueOf(password), getName());
return simpleAuthenticationInfo;
}
return null;
}
}
3.6.在myRealm中添加授权部分
//获取授权信息:进行授权工作
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
String adminid = (String) super.getAvailablePrincipal(principalCollection);
int id=Integer.parseInt(adminid);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//添加角色
Role role = adminService.getRoleByAdminId(id);
info.addRole(role.getRolename());
//添加权限
List<String> permissions = adminService.getPermissionsByRoleId(role.getId());
info.addStringPermissions(permissions);
return info;
}
3.7.在applicationContext.xml文件中添加权限设置:
3.8.出现异常(localhost 重定向次数过多)
原因: 在配置文件中filter 的配置为:/* 过滤了所有的访问,并且在filter的代码中有设置授权未通过时跳转到pages/403.jsp页面,但又设置了pages下所有页面未经授权无法访问,所以出现了死循环。
解决方法: 将403.jsp页面换个地方:
3.9.补充:数据库
4.Shiro框架中常用标签(jsp文件中)
在html标签之前,需要先引用标签库:<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
例如:<shiro:guest>中间可加任意html标签</shiro:guest>
<shiro:authenticated> 登录之后
<shiro:notAuthenticated> 不在登录状态时
<shiro:guest> 用户在没有RememberMe时
<shiro:user> 用户在RememberMe时
<shiro:hasAnyRoles name="abc,123" > 在有abc或者123角色时
<shiro:hasRole name="abc"> 拥有角色abc
<shiro:lacksRole name="abc"> 没有角色abc
<shiro:hasPermission name="abc"> 拥有权限资源abc
<shiro:lacksPermission name="abc"> 没有abc权限资源
<shiro:principal> 显示用户身份名称
<shiro:principal property="username"/> 显示用户身份中的属性值