网站建设实用教程,上海网站设计联系方式,马克杯在线设计网站,页面设计师简历什么是Shiro#xff1f;
一个Java的安全#xff08;权限#xff09;框架#xff0c;可以完成认证、授权、加密、会话管理、Web集成、缓存等
下载地址#xff1a;Apache Shiro | Simple. Java. Security. 快速启动
先在官网找到入门案例#xff1a;shiro/samples/quick…什么是Shiro
一个Java的安全权限框架可以完成认证、授权、加密、会话管理、Web集成、缓存等
下载地址Apache Shiro | Simple. Java. Security. 快速启动
先在官网找到入门案例shiro/samples/quickstart at main · apache/shiro · GitHub
步骤
1、新建一个 Maven 工程删除其 src 目录将其作为父工程
2、在父工程中新建一个 Maven 模块
3、在maven模块中复制依赖 dependenciesdependencygroupIdorg.apache.shiro/groupIdartifactIdshiro-core/artifactIdversion1.4.2/version/dependencydependencygroupIdorg.slf4j/groupIdartifactIdjcl-over-slf4j/artifactIdversion1.7.24/version/dependencydependencygroupIdorg.slf4j/groupIdartifactIdslf4j-log4j12/artifactIdversion1.7.21/version/dependencydependencygroupIdlog4j/groupIdartifactIdlog4j/artifactIdversion1.2.17/version/dependency/dependencies
4、复制 log4j.properties
log4j.rootLoggerINFO, stdoutlog4j.appender.stdoutorg.apache.log4j.ConsoleAppender
log4j.appender.stdout.layoutorg.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern%d %p [%c] - %m %n# General Apache libraries
log4j.logger.org.apacheWARN# Spring
log4j.logger.org.springframeworkWARN# Default Shiro logging
log4j.logger.org.apache.shiroINFO# Disable verbose logging
log4j.logger.org.apache.shiro.util.ThreadContextWARN
log4j.logger.org.apache.shiro.cache.ehcache.EhCacheWARN5、复制 shiro.ini要先在 IDEA中添加 ini 插件
[users]
# user root with password secret and the admin role
root secret, admin
# user guest with the password guest and the guest role
guest guest, guest
# user presidentskroob with password 12345 (Thats the same combination on
# my luggage!!! ;)), and role president
presidentskroob 12345, president
# user darkhelmet with password ludicrousspeed and roles darklord and schwartz
darkhelmet ludicrousspeed, darklord, schwartz
# user lonestarr with password vespa and roles goodguy and schwartz
lonestarr vespa, goodguy, schwartz# -----------------------------------------------------------------------------
# Roles with assigned permissions
#
# Each line conforms to the format defined in the
# org.apache.shiro.realm.text.TextConfigurationRealm#setRoleDefinitions JavaDoc
# -----------------------------------------------------------------------------
[roles]
# admin role has all permissions, indicated by the wildcard *
admin *
# The schwartz role can do anything (*) with any lightsaber:
schwartz lightsaber:*
# The goodguy role is allowed to drive (action) the winnebago (type) with
# license plate eagle5 (instance specific id)
goodguy winnebago:drive:eagle56、复制 Quickstart
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** ClassName Quickstart* Description TODO* Author GuoSheng* Date 2021/4/20 17:28* Version 1.0**/
public class Quickstart {private static final transient Logger log LoggerFactory.getLogger(Quickstart.class);public static void main(String[] args) {// The easiest way to create a Shiro SecurityManager with configured// realms, users, roles and permissions is to use the simple INI config.// Well do that by using a factory that can ingest a .ini file and// return a SecurityManager instance:// Use the shiro.ini file at the root of the classpath// (file: and url: prefixes load from files and urls respectively):DefaultSecurityManager defaultSecurityManagernew DefaultSecurityManager();IniRealm iniRealmnew IniRealm(classpath:shiro.ini);defaultSecurityManager.setRealm(iniRealm);// for this simple example quickstart, make the SecurityManager// accessible as a JVM singleton. Most applications wouldnt do this// and instead rely on their container configuration or web.xml for// webapps. That is outside the scope of this simple quickstart, so// well just do the bare minimum so you can continue to get a feel// for things.SecurityUtils.setSecurityManager(defaultSecurityManager);// Now that a simple Shiro environment is set up, lets see what you can do:// get the currently executing user:Subject currentUser SecurityUtils.getSubject();// Do some stuff with a Session (no need for a web or EJB container!!!)Session session currentUser.getSession();session.setAttribute(someKey, aValue);String value (String) session.getAttribute(someKey);if (value.equals(aValue)) {log.info(Retrieved the correct value! [ value ]);}// lets login the current user so we can check against roles and permissions:if (!currentUser.isAuthenticated()) {UsernamePasswordToken token new UsernamePasswordToken(lonestarr, vespa);token.setRememberMe(true);try {currentUser.login(token);} catch (UnknownAccountException uae) {log.info(There is no user with username of token.getPrincipal());} catch (IncorrectCredentialsException ice) {log.info(Password for account token.getPrincipal() was incorrect!);} catch (LockedAccountException lae) {log.info(The account for username token.getPrincipal() is locked. Please contact your administrator to unlock it.);}// ... catch more exceptions here (maybe custom ones specific to your application?catch (AuthenticationException ae) {//unexpected condition? error?}}//say who they are://print their identifying principal (in this case, a username):log.info(User [ currentUser.getPrincipal() ] logged in successfully.);//test a role:if (currentUser.hasRole(schwartz)) {log.info(May the Schwartz be with you!);} else {log.info(Hello, mere mortal.);}//test a typed permission (not instance-level)if (currentUser.isPermitted(lightsaber:wield)) {log.info(You may use a lightsaber ring. Use it wisely.);} else {log.info(Sorry, lightsaber rings are for schwartz masters only.);}//a (very powerful) Instance Level permission:if (currentUser.isPermitted(winnebago:drive:eagle5)) {log.info(You are permitted to drive the winnebago with license plate (id) eagle5. Here are the keys - have fun!);} else {log.info(Sorry, you arent allowed to drive the eagle5 winnebago!);}//all done - log out!currentUser.logout();System.exit(0);}
}
7、运行结果 Shiro的Subject分析
Quickstart 中的一些方法
1、获取当前用户
Subject currentUser SecurityUtils.getSubject();
2、通过当前用户拿到 Session
Session session currentUser.getSession();
3、用session存值取值 session.setAttribute(someKey, aValue);String value (String) session.getAttribute(someKey);
4、判断是否被认证
currentUser.isAuthenticated()
5、执行登录操作
currentUser.login(token);
6、打印其标识主体 currentUser.getPrincipal()
7、判断当前用户是否有某个角色
currentUser.hasRole(schwartz)
8、注销 currentUser.logout(); SpringBoot整合Shiro环境搭建
步骤
1、导入shiro的整合依赖 !--shiro整合spring--dependencygroupIdorg.apache.shiro/groupIdartifactIdshiro-spring/artifactIdversion1.4.1/version/dependency
2、在config包下编写Shiro的配置类
①自定义 Realm 类
public class UserRealm extends AuthorizingRealm {//授权Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {System.out.println(执行了shiro的授权方法);return null;}//认证Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {System.out.println(执行了shiro的认证方法);return null;}
}②自定义 ShiroConfig public class ShiroConfig {//ShiroFilterFactoryBeanBeanpublic ShiroFilterFactoryBean getShiroFilterFactoryBean(Autowired DefaultWebSecurityManager defaultWebSecurityManager){ShiroFilterFactoryBean bean new ShiroFilterFactoryBean();//设置安全管理器bean.setSecurityManager(defaultWebSecurityManager);return bean;}//DefaultWebSecurityManagerBeanpublic DefaultWebSecurityManager getDefaultWebSecurityManager(Autowired UserRealm userRealm){DefaultWebSecurityManager securityManager new DefaultWebSecurityManager();//关联 UserRealmsecurityManager.setRealm(userRealm);return securityManager;}//创建Realm对象需要自定义类Beanpublic UserRealm userRealm(){return new UserRealm();}
}Shiro实现登录拦截
功能必须认证了才能访问add和update页面没有认证直接跳到登录页面
步骤
1、编写前端页面
①编写首页
h1首页/h1
②编写测试页
登录首页的时候通过controller跳到测试页测试页包含可以跳到add和update页面的超链接
h1测试页/h1
p th:text${msg}/pa th:href{/user/add}add/aa th:href{/user/update}update/a
③add页面
h1add/h1
增加一个用户
④update页面
h1update/h1
修改一个用户
⑤登录页
h1登录/h1
form actiontoLogin用户名input typetext nameusername br密码 input typepassword namepassword brbutton typesubmit提交/button
/form
2、编写Controller
Controller
public class MyController {RequestMapping({/,/index,/index.html})public String toIndex(Model model){model.addAttribute(msg,hello,Shiro);return test;}RequestMapping(/user/add)public String add(){return user/add;}RequestMapping(/user/update)public String update(){return user/update;}RequestMapping(/toLogin)public String toLogin(){return login;}
}3、shiro配置登录拦截
Configuration
public class ShiroConfig {//ShiroFilterFactoryBeanBeanpublic ShiroFilterFactoryBean getShiroFilterFactoryBean(Autowired DefaultWebSecurityManager defaultWebSecurityManager){ShiroFilterFactoryBean bean new ShiroFilterFactoryBean();//设置安全管理器bean.setSecurityManager(defaultWebSecurityManager);//添加shiro的内置过滤器/*anon无需认证就可以访问authc必须认证了才能访问user必须拥有 记住我 功能才能访问perms拥有某个权限才能访问role拥有某个角色才能访问*/MapString, String filterMap new LinkedHashMap();filterMap.put(/user/add, authc);filterMap.put(/user/update, authc);bean.setFilterChainDefinitionMap(filterMap);//设置登录的请求bean.setLoginUrl(/toLogin);return bean;}//DefaultWebSecurityManagerBeanpublic DefaultWebSecurityManager getDefaultWebSecurityManager(Autowired UserRealm userRealm){DefaultWebSecurityManager securityManager new DefaultWebSecurityManager();//关联 UserRealmsecurityManager.setRealm(userRealm);return securityManager;}//创建Realm对象需要自定义类Beanpublic UserRealm userRealm(){return new UserRealm();}
}Shiro实现用户认证
步骤
1、在 UserRealm中编写认证方法 //认证Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {System.out.println(执行了shiro的认证方法);//用户名、密码要从数据库中获取String name root;String password 123456;UsernamePasswordToken userToken (UsernamePasswordToken)token;if(!userToken.getUsername().equals(name)){ //如果userToken中的username和数据库中取出来的name不一样return null; //抛出异常 UnknownAccountException}//密码认证shiro做return new SimpleAuthenticationInfo(,password,);}
2、在controller中封装用户数据 RequestMapping(/login)public String login(String username, String password, Model model){//获取当前用户Subject subject SecurityUtils.getSubject();//封装用户的登录数据UsernamePasswordToken token new UsernamePasswordToken(username, password);try{subject.login(token); //执行登录方法如果没有异常说明就ok了return index;}catch (UnknownAccountException e){ //用户名不存在model.addAttribute(msg,用户名错误);return login;}catch (IncorrectCredentialsException e){ //密码不存在model.addAttribute(msg,密码错误);return login;}} 步骤解析 Shiro整合MyBatis
步骤
1、导入依赖 dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.26/version/dependencydependencygroupIdcom.alibaba/groupIdartifactIddruid/artifactIdversion1.1.18/version/dependencydependencygroupIdlog4j/groupIdartifactIdlog4j/artifactIdversion1.2.17/version/dependencydependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactIdversion2.2.0/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.18.24/version/dependency
2、编写application.yaml和application.properties配置文件
①application.yaml
spring:datasource:username: rootpassword: 123456url: jdbc:mysql://localhost:3306/mybatis?useUnicodetruecharacterEncodingutf-8serverTimezoneUTCdriver-class-name: com.mysql.cj.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSource#Spring Boot 默认是不注入这些属性值的需要自己绑定#druid 数据源专有配置initialSize: 5minIdle: 5maxActive: 20maxWait: 60000timeBetweenEvictionRunsMillis: 60000minEvictableIdleTimeMillis: 300000validationQuery: SELECT 1 FROM DUALtestWhileIdle: truetestOnBorrow: falsetestOnReturn: falsepoolPreparedStatements: true#配置监控统计拦截的filtersstat:监控统计、log4j日志记录、wall防御sql注入#如果允许时报错 java.lang.ClassNotFoundException: org.apache.log4j.Priority#则导入 log4j 依赖即可Maven 地址https://mvnrepository.com/artifact/log4j/log4jfilters: stat,wall,log4jmaxPoolPreparedStatementPerConnectionSize: 20useGlobalDataSourceStat: trueconnectionProperties: druid.stat.mergeSqltrue;druid.stat.slowSqlMillis500
②application.properties
mybatis.type-aliases-packagecom.pojo
mybatis.mapper-locationsclasspath:mapper/*.xml3、编写实体类
Data
AllArgsConstructor
NoArgsConstructor
public class User implements Serializable {private int id;private String name;private String pwd;
}4、编写mapper层
①UserMapper接口
Repository
Mapper
public interface UserMapper {//根据用户名查用户信息public User queryUserByName(String name);
}②UserMapper.xml
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttps://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.mapper.UserMapperselect idqueryUserByName parameterTypeString resultTypeUserselect * from mybatis.user where name #{name};/select
/mapper
5、编写service层
①UserService接口
public interface UserService{public User queryUserByName(String name);
}②UserServiceImpl
Service
public class UserServiceImpl implements UserService{AutowiredUserMapper userMapper;Overridepublic User queryUserByName(String name) {return userMapper.queryUserByName(name);}
}6、把之前在UserRealm中直接写的name和password改成从数据库中查出来的
public class UserRealm extends AuthorizingRealm {AutowiredUserServiceImpl userService;//授权Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {System.out.println(执行了shiro的授权方法);return null;}//认证Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {System.out.println(执行了shiro的认证方法);UsernamePasswordToken userToken (UsernamePasswordToken)token;//连接真实的数据库User user userService.queryUserByName(userToken.getUsername());//如果user为空说明用户不存在if(user null){return null; //抛异常 UnknownAccountException}//密码认证shiro做return new SimpleAuthenticationInfo(,user.getPwd(),);}
}Shiro请求授权实现
1、在ShiroConfig中设置访问哪些路径需要哪些权限并配置未授权页面 filterMap.put(/user/add,perms[user:add]); //拥有 user:add 权限才能访问/user/addfilterMap.put(/user/update,perms[user:update]); bean.setUnauthorizedUrl(/noauth); 2、在UserRealm中给当前用户授权其中权限是从数据库中查出来的 Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {System.out.println(执行了shiro的授权方法);SimpleAuthorizationInfo info new SimpleAuthorizationInfo();//拿到当前登录的这个对象Subject subject SecurityUtils.getSubject();User currentUser (User)subject.getPrincipal(); //拿到user对象info.addStringPermission(currentUser.getPerms());return info;} 3、在controller中设置未授权url处理 RequestMapping(/noauth)ResponseBodypublic String unauthorized(){return 未经授权无法访问此页面;} Shiro整合Thymeleaf
1、导入依赖 !--shiro-thymeleaf整合--dependencygroupIdcom.github.theborakompanioni/groupIdartifactIdthymeleaf-extras-shiro/artifactIdversion2.0.0/version/dependency
2、在shiroConfig中整合thymeleaf //ShiroDialect用来整合 shiro thymeleafBeanpublic ShiroDialect getShiroDialect(){return new ShiroDialect();} 3、更改前端页面
①在test页面编写一个登录连接
pa th:href{/toLogin}登录/a
/p②在首页设置add和update链接拥有对应权限才可以访问 shiro命名空间
xmlns:shirohttp://www.thymeleaf.org/thymeleaf-extras-shiro
链接
div shiro:hasPermissionuser:adda th:href{/user/add}add/a
/divdiv shiro:hasPermissionuser:updatea th:href{/user/update}update/a
/div