Java合作开发虚拟化职权信息系统 Spring Security/Apache Shiro对照预测
下栽の地止:https://www.itwangzi.cn/4486.html
Java合作开发民营企业及职权信息系统 Spring Se
Apache Shiro 是两个 Java 的安全可靠(职权)架构。Shiro 能极难的合作开发出足够多好的应用领域,其不但能用在 JavaSE 自然环境,也能用在 JavaEE 自然环境。Shiro 能顺利完成,证书,许可,身份验证,会话管理工作,Web软件系统,内存等.
2、Shiro OWL构筑
增建两个Spring Boot工程项目spring-boot-08-shiro,加进web、thymeleaf架构。
2.1、导入 shiro 依赖
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring-boot-web-starter</artifactId><version>1.8.0</version></dependency>
2.2、编写 shiro 配置类
在配置类中需要注入三个 Bean:ShiroFilterFactoryBean、DefaultWebSecurityManager、UserRealm。
第一步:创建 Realm 对象,需要自定义类继承 AuthorizingRealm,重写证书和许可部分方法。
package com.thomas.config;importorg.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;importorg.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authz.AuthorizationInfo;importorg.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;publicclassUserRealmextendsAuthorizingRealm{//许可@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection){ System.out.println(“执行了===>许可”);returnnull; }//证书@OverrideprotectedAuthenticationInfodoGetAuthenticationInfo(AuthenticationToken authenticationToken)throwsAuthenticationException{ System.out.println(“执行了========>证书”);returnnull; }}
package com.thomas.config;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;importorg.apache.shiro.web.mgt.DefaultWebSecurityManager;import org.springframework.beans.factory.annotation.Qualifier;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;@ConfigurationpublicclassShiroConfig{@Beanpublic UserRealm userRealm(){returnnew UserRealm(); }}
第二步:将UserRealm对象设置到defaultWebSecurityManager
@Bean(name = “webSecurityManager”)publicDefaultWebSecurityManagerdefaultWebSecurityManager(@Qualifier(value = “userRealm”) UserRealm userRealm) {DefaultWebSecurityManager webSecurityManager =new DefaultWebSecurityManager(); webSecurityManager.setRealm(userRealm);return webSecurityManager;}
第三步:将defaultWebSecurityManager设置到ShiroFilterFactoryBean
@BeanpublicShiroFilterFactoryBeanshiroFilterFactoryBean(@Qualifier(value = “webSecurityManager”)DefaultWebSecurityManager defaultWebSecurityManager){ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);return shiroFilterFactoryBean;}
2.3、编写 controller
在 controller 层,我们实现简单的页面跳转功能。跳转首页,跳转/usr/update, /usr/add
packagecom.thomas.controller;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;importorg.springframework.web.bind.annotation.GetMapping;@ControllerpublicclassMyController{@GetMapping({“/”, “/index”})public String toIndex(Model model){ model.addAttribute(“msg”, “Hello, shiro”);return“index”; }@GetMapping(“/usr/add”)public String add(){return“user/add”; }@GetMapping(“/usr/update”)public String update(){return“user/update”; }}
2.4、编写前端页面
<!doctype html><htmllang=“en”><head><metacharset=“UTF-8”><metaname=“viewport”content=“width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0”><metahttp-equiv=“X-UA-Compatible”content=“ie=edge”><title>Document</title></head><body><h1>首页</h1><pth:text=“${msg}”></p><hr><ath:href=“@{/usr/add}”>add</a> | <ath:href=“@{/usr/update}”>update</a></body></html>
<!DOCTYPE html><htmllang=“en”><head><metacharset=“UTF-8”><title>Title</title></head><body><h1>add</h1></body></html>
<!DOCTYPE html><htmllang=“en”><head><metacharset=“UTF-8”><title>Title</title></head><body><h1>update</h1></body></html>
3、Shiro 实现登录拦截
shiro有内置过滤器,是通过DefaultFilter枚举类来实现的,在其中定义了常见的过滤器,我们能借助这些过滤器来实现拦截请求。
3.1、设置登录验证
我们在ShiroFilterFactoryBean中设置加进 shiro 的内置过滤器,将前面的两个页面设置为authc
@Beanpublic ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier(value = “webSecurityManager”)DefaultWebSecurityManager defaultWebSecurityManager){ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();//设置安全可靠管理工作器shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);//加进shiro的内置过滤器
/*
* anon: 无需证书就能访问
* authc: 必须证书了才能访问
* user: 必须拥有 记住我 功能才能用
* perms: 拥有对某个资源的职权才能访问
* role: 拥有某个角色职权才能访问
* */
Map<String, String> map =new HashMap<>();//map.put(“/usr/add”, “authc”);//map.put(“/usr/update”, “authc”);//支持通配符map.put(“/usr/*”, “authc”); shiroFilterFactoryBean.setFilterChainDefinitionMap(map);returnshiroFilterFactoryBean;}
重新启动工程项目,测试发现无法访问,此时我们的请求被成功拦截。
3.2、登录页面
当页面需要登录职权而用户未登录时,此时应该跳转到登录页面。
<!DOCTYPE html><htmllang=“en”><head><metacharset=“UTF-8”><title>登录</title></head><body><h1>登录</h1><hr><formaction=“”><p>用户名: <inputtype=“text”name=“username”></p><p>密码: <inputtype=“password”name=“password”></p><p><inputtype=“submit”></p></form>
package com.thomas.controller;importorg.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;@ControllerpublicclassMyController{ …@RequestMapping(“/toLogin”)public String toLogin(){return“login”; }}
package com.thomas.config;importorg.apache.shiro.spring.web.ShiroFilterFactoryBean;importorg.apache.shiro.web.mgt.DefaultWebSecurityManager;import org.springframework.beans.factory.annotation.Qualifier;importorg.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;importjava.util.HashMap;import java.util.Map;@ConfigurationpublicclassShiroConfig{//ShiroFilterFactoryBean:第三步@BeanpublicShiroFilterFactoryBeanshiroFilterFactoryBean(@Qualifier(value = “webSecurityManager”)DefaultWebSecurityManager defaultWebSecurityManager){ ShiroFilterFactoryBean shiroFilterFactoryBean = newShiroFilterFactoryBean();//设置安全可靠管理工作器 shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);//加进shiro的内置过滤器
/*
* anon: 无需证书就能访问
* authc: 必须证书了才能访问
* user: 必须拥有 记住我 功能才能用
* perms: 拥有对某个资源的职权才能访问
* role: 拥有某个角色职权才能访问
* */
Map<String, String> map = new HashMap<>();// map.put(“/usr/add”, “authc”);// map.put(“/usr/update”, “authc”); map.put(“/usr/*”, “authc”); shiroFilterFactoryBean.setFilterChainDefinitionMap(map);//设置登录页面 shiroFilterFactoryBean.setLoginUrl(“/toLogin”);return shiroFilterFactoryBean; }…}
测试,访问/usr/add,/usr/update页面即可实现跳转到登录页面。
4、Shiro 实现用户证书
4.1、用户证书
用户证书功能主要是通过Realm对象来实现的。我们先编写/login请求,封装用户登录数据,执行登录方法
@RequestMapping(“/login”)public String login(String username, String password, Model model){Subject subject = SecurityUtils.getSubject();//封装用户的登录数据 UsernamePasswordToken token = newUsernamePasswordToken(username, password);try { subject.login(token); //执行登录方法,如果没有异常就说明登录成功return“index”; } catch(UnknownAccountException e) {//用户名不存在 model.addAttribute(“msg”, “用户名错误”);return“login”; } catch(IncorrectCredentialsException e) {//密码错误 model.addAttribute(“msg”, “密码错误”);return“login”; }}
<!DOCTYPEhtml><htmllang=“en”xmlns:th=“http://www.thymeleaf.org”><head><metacharset=“UTF-8”><title>登录</title></head><body><h1>登录</h1><pth:text=“${msg}”style=“color: red”></p><hr><formth:action=“@{/login}”><p>用户名: <inputtype=“text”name=“username”></p><p>密码: <inputtype=“password”name=“password”></p><p><inputtype=“submit”></p></form></body></html>
重新启动,点击登录,在控制台能看到执行了Realm中的证书。
4.2、用户身份证书
用户实现登录功能,还需要进行校验,在UserRealm中顺利完成证书功能。
@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)throws AuthenticationException { System.out.println(“执行了========>证书”);//用户名,密码 从数据中取String name =“root”; String password = “123456”;UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;if (!userToken.getUsername().equals(name)) {//用户名不一致returnnull; //抛出异常 UnknownAccountException }//密码验证,交给shiro实现returnnew SimpleAuthenticationInfo(“”, password, “”);}
5、Shiro 整合 Mybatis
5.1、导入相关包
包括druid数据源、jdbc、mybatis、mysql
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.17</version></dependency><!– https://mvnrepository.com/artifact/log4j/log4j –><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.0</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency>
5.2、配置 mybatis 以及数据源
spring:datasource:username:用户名password:密码driver-class-name:com.mysql.cj.jdbc.Driverurl:jdbc:mysql://localhost:3306/mybatis?useUnicode=true&useUnicode=true&characterEncoding=utf-8type:com.alibaba.druid.pool.DruidDataSource#Spring Boot 默认是不注入这些属性值的,需要自己绑定#druid 数据源专有配置initialSize:5minIdle:5maxActive:20maxWait:60000timeBetweenEvictionRunsMillis:60000minEvictableIdleTimeMillis:300000validationQuery:SELECT1FROMDUALtestWhileIdle:truetestOnBorrow:falsetestOnReturn:falsepoolPreparedStatements:true#配置监控统计拦截的filters,stat:监控统计、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.mergeSql=true;druid.stat.slowSqlMillis=500
mybatis.type-aliases-package=com.thomas.pojo
mybatis.mapper-locations=classpath:mapper/*.xml
5.3、编写实体类、mapper 相关接口和实现类
package com.thomas.pojo;importlombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;@Data@AllArgsConstructor@NoArgsConstructorpublicclassUser{privateint id;private String name;privateint age;private String password;}
mapper/UserMapper.java(接口)
package com.thomas.mapper;import com.thomas.pojo.User;import org.apache.ibatis.annotations.Mapper;import org.springframework.stereotype.Repository;@Repository@MapperpublicinterfaceUserMapper{publicUserqueryUserByName(String name);}
Resources/mapper/UserMapper.xml
<?xml version=”1.0″ encoding=”UTF-8″ ?><!DOCTYPE mapperPUBLIC“-//mybatis.org//DTD Mapper 3.0//EN”“http://mybatis.org/dtd/mybatis-3-mapper.dtd”><mappernamespace=“com.thomas.mapper.UserMapper”><selectid=“queryUserByName”resultType=“User”>select * from mybatis.user where `name` = #{name}</select></mapper>
service/UserService.java(接口)
packagecom.thomas.service;import com.thomas.pojo.User;publicinterfaceUserService{public User queryUserByName(String name);}
service/UserServiceImpl.java
package com.thomas.service;importcom.thomas.mapper.UserMapper;import com.thomas.pojo.User;import org.springframework.stereotype.Service;importjavax.annotation.Resource;@ServicepublicclassUserServiceImplimplementsUserService{@Resource UserMapper userMapper;@Overridepublic User queryUserByName(String name){return userMapper.queryUserByName(name); }}
5.4、在 Shiro 中使用 mybatis
package com.thomas.config;import com.thomas.mapper.UserMapper;importcom.thomas.pojo.User;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.*;importorg.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;importorg.apache.shiro.subject.PrincipalCollection;import org.apache.shiro.subject.Subject;importorg.apache.shiro.util.StringUtils;import javax.annotation.Resource;publicclassUserRealmextendsAuthorizingRealm{@ResourceUserMapper userMapper;
//
许可
@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection){ System.out.println(“执行了===>许可”);returnnull; }//证书@OverrideprotectedAuthenticationInfodoGetAuthenticationInfo(AuthenticationToken authenticationToken)throws AuthenticationException {System.out.println(“执行了========>证书”);UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;//用户名,密码 从数据库中取 User user = userMapper.queryUserByName(userToken.getUsername());if (user == null) {//用户名不一致returnnull; //抛出异常 UnknownAccountException }//密码验证,交给shiro实现returnnewSimpleAuthenticationInfo(“”, user.getPassword(), “”); }}
总结
以上就是关于 Shiro 的学习内容了。从功能上看,Shiro 提供了与 SpringSecurity 高度相似的功能,相对而言,Shiro 会更简单,容易上手。