手机电子商务网站建设,华为商城网站建设,制作京东网站建设,网站模板 哪家好1、概述
Apache Shiro 是一个功能强大且易于使用的 Java 安全(权限)框架。借助 Shiro 您可以快速轻松地保护任何应用程序一一从最小的移动应用程序到最大的 Web 和企业应用程序。
作用#xff1a;Shiro可以帮我们完成 #xff1a;认证、授权、加密、会话管理、与 Web 集成、…1、概述
Apache Shiro 是一个功能强大且易于使用的 Java 安全(权限)框架。借助 Shiro 您可以快速轻松地保护任何应用程序一一从最小的移动应用程序到最大的 Web 和企业应用程序。
作用Shiro可以帮我们完成 认证、授权、加密、会话管理、与 Web 集成、缓存等。
2、Shiro 与 SpringSecurity 的对比
1、Spring Security 基于 pring 开发项目若使用 Spring 作为基础配合 SpringSecurity 做权限更加方便而 Shiro需要和 Spring 进行整合开发2、Spring Security 功能比 Shiro 更加丰富些例如安全维护方面3、Spring Security 社区资源相对比 Shiro 更加丰富:4、Shiro的配置和使用比较简单Spring Security 上手复杂些5、Shiro 依赖性低不需要任何框架和容器可以独立运行.Spring Security 依赖Spring容器6、shiro 不仅仅可以使用在 web 中它可以工作在任何应用环境中。在集群会话时 Shiro最重要的一个好处或许就是它的会话是独立于容器的
3、Shiro核心架构 Subject即主体外部应用与subject进行交互subject记录了当前的操作用户将用户的概念理解为当前操作的主体。外部程序通过subject进行认证授权而subject是通过SecurityManager安全管理器进行认证授权 SecurityManager即安全管理器对全部的subject进行安全管理它是shiro的核心负责对所有的subject进行安全管理。通过SecurityManager可以完成subject的认证、授权等实质上SecurityManager是通过Authenticator进行认证通过Authorizer进行授权通过SessionManager进行会话管理等 SecurityManager是一个接口继承了Authenticator, Authorizer, SessionManager这三个接口 Authenticator即认证器对用户身份进行认证Authenticator是一个接口shiro提供ModularRealmAuthenticator实现类通过ModularRealmAuthenticator基本上可以满足大多数需求也可以自定义认证器 Authorizer即授权器用户通过认证器认证通过在访问功能时需要通过授权器判断用户是否有此功能的操作权限 Realm即领域相当于datasource数据源securityManager进行安全认证需要通过Realm获取用户权限数据比如如果用户身份数据在数据库那么realm就需要从数据库获取用户身份信息 sessionManager即会话管理shiro框架定义了一套会话管理它不依赖web容器的session所以shiro可以使用在非web应用上也可以将分布式应用的会话集中在一点管理此特性可使它实现单点登录 SessionDAO即会话dao是对session会话操作的一套接口比如要将session存储到数据库可以通过jdbc将会话存储到数据库 CacheManager即缓存管理将用户权限数据存储在缓存这样可以提高性能Cryptography Cryptography即密码管理shiro提供了一套加密/解密的组件方便开发。比如提供常用的散列、加/解密等功能。 token
1、token定义服务端生成的一串字符串可以解决频繁登录的问题 作为客户端进行请求的一个令牌
第一次登录后服务器生成一个token返回给客户端客户端只需要带上token来请求数据即可无需再次带上用户名和密码;
2、目的为了减轻服务器的压力减少频繁的查询数据库使服务器更加健壮
4、Shiro的登录认证 1.创建数据库并创建用户表 2.创建项目病配置ssm完成根据用户名查询用户信息 3.创建自定义Realm继承AuthorizingRealm使用mybtais查询数据库的盐值和密码交给shiro进行验证 流程 1.数据库与表创建
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS 0;-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS user;
CREATE TABLE user (uid int(11) NOT NULL AUTO_INCREMENT,uname varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,pwd varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,sex varchar(2) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,address varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,state int(2) DEFAULT NULL,salt varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,PRIMARY KEY (uid) USING BTREE,UNIQUE INDEX uname(uname) USING BTREE
) ENGINE InnoDB AUTO_INCREMENT 4 CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT Dynamic;-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO user VALUES (1, admin, 727d8b2b4c59366d7ace58d4eda4cfee, 女, 河南洛阳, 1, 9C2AB20283F9450389330033D64686DD);
INSERT INTO user VALUES (2, zs, 83f12ba7c4357b87167e240a22c15248, 男, 河南郑州, 1, 262F995823C94D1CAE7596B47E8AB657);select * from user2.创建模块项目使用mavenssmshiro 3.搭建ssm框架编写根据用户名查询用户信息的三层架构
shiro在spring.xml中的配置 dao层
Repository
public interface UserDao {Select(select * from user where uname #{uname})User selectByName(String uname);
} service层
public interface UserService {User selectByName(String uname);
}
实现类
Service
public class UserServiceImpl implements UserService {AutowiredUserDao userDao;Overridepublic User selectByName(String uname) {return userDao.selectByName(uname);}
}
controller层进行shiro认证
Controller
public class UserController {RequestMapping(/login)public String login(String uname, String pwd, HttpSession session){//1 获取 Subject 对象Subject subject SecurityUtils.getSubject();//2 封装请求数据到 token 对象中AuthenticationToken token new UsernamePasswordToken(uname,pwd);//3 调用 login 方法进行登录认证try{//验证主体是否能够登录subject.login(token);session.setAttribute(user,token.getPrincipal().toString());return main;}catch(UnknownAccountException e){System.out.println(用户名不存在);return login;}catch(IncorrectCredentialsException e){System.out.println(密码错误);return login;}catch(AuthenticationException e){System.out.println(登录失败);return login;}}
}
/*** 地址和页面的映射项目中没有页面请求全是地址请求*/
Controller
public class PageController {RequestMapping({/,/index})public String index(){return index;}RequestMapping(/loginUI)public String home(){return login;}RequestMapping(/main)public String phone(){return main;}}
web.xml中配置shiro的过滤器
!-- shiro配置 --
filter
filter-nameshiroFilter/filter-name
filter-classorg.springframework.web.filter.DelegatingFilterProxy/filterclass
init-param
param-nametargetFilterLifecycle/param-name
param-valuetrue/param-value
/init-param
/filter
filter-mapping
filter-nameshiroFilter/filter-name
url-pattern/*/url-pattern
/filter-mapping
shiro层测试
public class Shiro01 {public static void main(String[] args) {
// //Java加盐加密
// Digester md5 new Digester(DigestAlgorithm.MD5);
// md5.setSalt(9C2AB20283F9450389330033D64686DD.getBytes());//加盐
// md5.setDigestCount(1024);//加散列值
// String md5Pwd md5.digestHex(123);
// System.out.println(md5Pwd);//控制台获取Scanner sc new Scanner(System.in);System.out.println(请输入用户名);String username sc.next();System.out.println(请输入密码);String password sc.next();//1.使用INi格式工厂模型来创建对象IniSecurityManagerFactory securityManagerFactory new IniSecurityManagerFactory(classpath:shiro.ini);//2.获取安全管理器SecurityManager securityManager securityManagerFactory.getInstance();//3.让安全管理器开始工作SecurityUtils.setSecurityManager(securityManager);//4.获取系统访问的主体就是登录系统的用户信息Subject subject SecurityUtils.getSubject();//4.1模拟客户端传输过来的用户名和密码---创建对应的令牌 tokenAuthenticationToken token new UsernamePasswordToken(username,password);try{//5.验证主体是否能够登录subject.login(token);System.out.println(登录成功);}catch(UnknownAccountException e){System.out.println(用户名不存在);}catch(IncorrectCredentialsException e){System.out.println(密码错误);}catch(AuthenticationException e){System.out.println(认证失败不知道出了什么问题);}}
}
创建MyRealm继承AuthorizingRealm
package com.zhan.shiro;import com.zhan.bean.User;
import com.zhan.service.UserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;/*** token 里面是客户端发来的信息包含输入的用户名和密码* 自定义Realm,通过mybatis查询数据库的密码和盐值让shiro进行身份验证*/
Component
public class MyRealm extends AuthorizingRealm {AutowiredUserService userService;/*** shiro 进行授权操作* param principals* return*/Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {return null;}/*** shiro 进行认证操作* param token* return* throws AuthenticationException*/Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {//token 是主体传过来的身份令牌//1.获取用户身份信息String uname token.getPrincipal().toString();//2.调用业务层获取永固信息(数据库中User user userService.selectByName(uname);//判断并将数据完成封装if(user!null){AuthenticationInfo authenticationInfo new SimpleAuthenticationInfo(token.getPrincipal(),//令牌身份信息对象user.getPwd(),//用户数据库的密码ByteSource.Util.bytes(user.getSalt().getBytes()),//加密时的盐值uname//用户名);return authenticationInfo;}return null;}
}