SpringBoot学习-(十七)SpringBoot整合Shiro
来源:互联网 发布:12306手机购票软件 编辑:程序博客网 时间:2024/06/02 04:37
基本步骤:
- 添加pom文件依赖
- 书写自定义的realm
- 配置shiro
- 控制层使用
项目目录结构:
1.添加pom文件依赖
<!-- spring整合shiro --><!-- maven会自动添加shiro-core,shiro-web依赖 --><dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.3.2</version></dependency>
2.书写自定义realm
package com.ahut.shiro;import java.util.ArrayList;import java.util.List;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.authc.UsernamePasswordToken;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import org.apache.shiro.util.ByteSource;/** * * @ClassName: MyRealm * @Description: 自定义realm * @author cheng * @date 2017年10月9日 上午10:54:00 */public class MyRealm extends AuthorizingRealm { /** * 用于认证 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("使用了自定义的realm,用户认证..."); System.out.println("用户名:" + ((UsernamePasswordToken) token).getUsername()); System.out.println("密码:" + new String(((UsernamePasswordToken) token).getPassword())); // 模拟账号不存在 // if (true) { // throw new UnknownAccountException(); // } // 获取用户名 String userName = (String) token.getPrincipal(); // 依据用户名去数据库查询 // 模拟从数据库中查询出来的散列值密码 String password = "36f2dfa24d0a9fa97276abbe13e596fc"; // 查询到了数据,验证密码是否正确 // 密码正确,认证通过 // 密码错误,认证失败 // 没有查询到数据,认证失败 // 模拟从数据库中获取salt String salt = "qwerty"; return new SimpleAuthenticationInfo(userName, password, ByteSource.Util.bytes(salt), this.getName()); } /** * 用于授权 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { System.out.println("使用了自定义的realm,用户授权..."); // 获取用户名 // String userName = (String) principals.getPrimaryPrincipal(); // 依据用户名在数据库中查找权限信息 // 角色 List<String> roles = new ArrayList<>(); roles.add("admin"); roles.add("user"); // 权限 List<String> permissions = new ArrayList<>(); permissions.add("admin:select"); permissions.add("admin:delete"); SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); simpleAuthorizationInfo.addStringPermissions(permissions); simpleAuthorizationInfo.addRoles(roles); return simpleAuthorizationInfo; }}
3.配置shiro
package com.ahut.config;import java.util.LinkedHashMap;import java.util.Map;import org.apache.shiro.mgt.SecurityManager;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;import org.apache.shiro.web.mgt.DefaultWebSecurityManager;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import com.ahut.shiro.MyRealm;/** * * @ClassName: ShiroConfig * @Description: spring整合shiro配置 * @author cheng * @date 2017年10月10日 上午9:46:43 */@Configurationpublic class ShiroConfig { /** * * @Title: createMyRealm * @Description: 自定义的realm * @return */ @Bean public MyRealm createMyRealm() { return new MyRealm(); } /** * * @Title: securityManager * @Description: 注入自定义的realm * @Description: 注意方法返回值SecurityManager为org.apache.shiro.mgt.SecurityManager * ,不要导错包 * @return */ @Bean public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(createMyRealm()); return securityManager; } /** * * @Title: shirFilter * @Description: Shiro 的Web过滤器 * @param securityManager * @return */ @Bean public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面 shiroFilterFactoryBean.setLoginUrl("/userLogin"); // 登录成功后要跳转的链接,建议不配置,shiro认证成功自动到上一个请求路径 shiroFilterFactoryBean.setSuccessUrl("/index"); // 未授权界面,指定没有权限操作时跳转页面 shiroFilterFactoryBean.setUnauthorizedUrl("/403"); // 过滤器 Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>(); // 配置不会被过滤的链接 顺序判断 // 过虑器链定义,从上向下顺序执行,一般将/**放在最下边 // 对静态资源设置匿名访问 // anon:所有url都都可以匿名访问 filterChainDefinitionMap.put("/static/**", "anon"); // 配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了 filterChainDefinitionMap.put("/logout", "logout"); // authc:所有url都必须认证通过才可以访问 filterChainDefinitionMap.put("/**", "authc"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; }}
代码说明:
1.自定义的realm和注入自定义的realm相当于以前的shiro.ini文件
#自定义的realmmyRealm=com.ahut.test.MyRealm# 注入自定义的realmsecurityManager.realms=$myRealm
2.ShiroFilterFactoryBean相当于以下xml配置
<!-- web.xml中shiro的filter对应的bean --><!-- Shiro 的Web过滤器 --><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager" /> <!-- loginUrl认证提交地址,如果没有认证将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 --> <property name="loginUrl" value="/login.action" /> <!-- 认证成功统一跳转到first.action,建议不配置,shiro认证成功自动到上一个请求路径 --> <property name="successUrl" value="/first.action"/> <!-- 通过unauthorizedUrl指定没有权限操作时跳转页面--> <property name="unauthorizedUrl" value="/refuse.jsp" /> <!-- 自定义filter配置 --> <property name="filters"> <map> <!-- 将自定义 的FormAuthenticationFilter注入shiroFilter中--> <entry key="authc" value-ref="formAuthenticationFilter" /> </map> </property> <!-- 过虑器链定义,从上向下顺序执行,一般将/**放在最下边 --> <property name="filterChainDefinitions"> <value> <!-- 对静态资源设置匿名访问 --> /images/** = anon /js/** = anon /styles/** = anon <!-- 验证码,可匿名访问 --> /validatecode.jsp = anon <!-- 请求 logout.action地址,shiro去清除session--> /logout.action = logout <!--商品查询需要商品查询权限 ,取消url拦截配置,使用注解授权方式 --> <!-- /items/queryItems.action = perms[item:query] /items/editItems.action = perms[item:edit] --> <!-- 配置记住我或认证通过可以访问的地址 --> /index.jsp = user /first.action = user /welcome.jsp = user <!-- /** = authc 所有url都必须认证通过才可以访问--> /** = authc <!-- /** = anon所有url都可以匿名访问 --> </value> </property></bean><!-- securityManager安全管理器 --><bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="customRealm" /> <!-- 注入缓存管理器 --> <property name="cacheManager" ref="cacheManager"/> <!-- 注入session管理器 --> <property name="sessionManager" ref="sessionManager" /> <!-- 记住我 --> <property name="rememberMeManager" ref="rememberMeManager"/> </bean><!-- realm --><bean id="customRealm" class="cn.itcast.ssm.shiro.CustomRealm"> <!-- 将凭证匹配器设置到realm中,realm按照凭证匹配器的要求进行散列 --> <property name="credentialsMatcher" ref="credentialsMatcher"/></bean><!-- 凭证匹配器 --><bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <property name="hashAlgorithmName" value="md5" /> <property name="hashIterations" value="1" /></bean><!-- 缓存管理器 --><bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> <property name="cacheManagerConfigFile" value="classpath:shiro-ehcache.xml"/></bean><!-- 会话管理器 --><bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> <!-- session的失效时长,单位毫秒 --> <property name="globalSessionTimeout" value="600000"/> <!-- 删除失效的session --> <property name="deleteInvalidSessions" value="true"/></bean><!-- 自定义form认证过虑器 --><!-- 基于Form表单的身份验证过滤器,不配置将也会注册此过虑器,表单中的用户账号、密码及loginurl将采用默认值,建议配置 --><bean id="formAuthenticationFilter" class="cn.itcast.ssm.shiro.CustomFormAuthenticationFilter "> <!-- 表单中账号的input名称 --> <property name="usernameParam" value="username" /> <!-- 表单中密码的input名称 --> <property name="passwordParam" value="password" /> <!-- 记住我input的名称 --> <property name="rememberMeParam" value="rememberMe"/></bean><!-- rememberMeManager管理器,写cookie,取出cookie生成用户信息 --><bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager"> <property name="cookie" ref="rememberMeCookie" /></bean><!-- 记住我cookie --><bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie"> <!-- rememberMe是cookie的名字 --> <constructor-arg value="rememberMe" /> <!-- 记住我cookie生效时间30天 --> <property name="maxAge" value="2592000" /></bean>
4.控制层使用
package com.ahut.action;import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.DisabledAccountException;import org.apache.shiro.authc.ExcessiveAttemptsException;import org.apache.shiro.authc.ExpiredCredentialsException;import org.apache.shiro.authc.IncorrectCredentialsException;import org.apache.shiro.authc.LockedAccountException;import org.apache.shiro.authc.UnknownAccountException;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.subject.Subject;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;/** * * @ClassName: ShiroAction * @Description: shiro控制层 * @author cheng * @date 2017年10月10日 上午10:18:21 */@RestControllerpublic class ShiroAction { /** * * @Title: userLogin * @Description: 用户登录 * @return */ @RequestMapping(value = "/userLogin") public String userLogin(String username, String password) { // 以下部分在配置阶段就已经完成,可以直接使用 // 读取配置文件 // Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini"); // 获取SecurityManager的实例 // SecurityManager securityManager = factory.getInstance(); // 把 securityManager 的实例绑定到 SecurityUtils 上 // SecurityUtils.setSecurityManager(securityManager); System.out.println(username + ":" + password); Subject subject = SecurityUtils.getSubject(); // 自己创建一个令牌,输入用户名和密码 UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password); try { subject.login(usernamePasswordToken); System.out.println("身份认证成功!"); } catch (UnknownAccountException e) { e.printStackTrace(); System.out.println("账号不存在!"); } catch (LockedAccountException e) { e.printStackTrace(); System.out.println("账号被锁定!"); } catch (DisabledAccountException e) { e.printStackTrace(); System.out.println("账号被禁用!"); } catch (IncorrectCredentialsException e) { e.printStackTrace(); System.out.println("凭证/密码错误!"); } catch (ExpiredCredentialsException e) { e.printStackTrace(); System.out.println("凭证/密码过期!"); } catch (ExcessiveAttemptsException e) { e.printStackTrace(); System.out.println("登录失败次数过多!"); } // 是否认证通过 boolean isAuthenticated1 = subject.isAuthenticated(); System.out.println("登录后,是否认证通过:" + isAuthenticated1); // 退出 subject.logout(); // 是否认证通过 boolean isAuthenticated2 = subject.isAuthenticated(); System.out.println("退出登录后,是否认证通过:" + isAuthenticated2); return "处理登录"; }}
阅读全文
0 0
- SpringBoot学习-(十七)SpringBoot整合Shiro
- SpringBoot学习:整合shiro(rememberMe记住我功能)
- springboot shiro 整合
- springboot shiro 整合
- springboot整合shiro
- SpringBoot整合Shiro
- SpringBoot整合shiro框架
- springboot 整合shiro
- SpringBoot学习-(六)SpringBoot与Mybatis整合
- SpringBoot学习-(十八)SpringBoot整合EhCache
- SpringBoot学习:SpringBoot整合mybatis
- SpringBoot+shiro整合学习之登录认证和权限控制
- SpringBoot+shiro整合学习之登录认证和权限控制
- SpringBoot学习:整合shiro(身份认证和权限认证),使用EhCache缓存
- SpringBoot学习:整合shiro(验证码功能和登录次数限制功能)
- SpringBoot学习:整合shiro(rememberMe记住我后自动登录session失效解决办法)
- SpringBoot学习:整合shiro(rememberMe记住我后自动登录session失效解决办法)
- SpringBoot学习:整合Redis
- python 报错记录
- error LINK2038:mismatch detected for '_MSC_VER':value '1900' doen't match value '1800'
- asp.net core后台系统登录的快速构建
- C# 文件直接打印功能
- Java 发送邮件
- SpringBoot学习-(十七)SpringBoot整合Shiro
- CSS3中浏览器的兼容性
- Linux -- 解压命令介绍
- Rendering Problems Missing styles. Is the correct theme chosen for this layout?
- Asp.Net Core 2.0 多角色权限认证
- HardFault_Handler问题查找方法
- JAVA Scanner用法详解
- 笔试题1
- mysql 5.5 和5.7 安装的区别