Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、受权、密码和会话管理。使用Shiro的易于理解的API,您能够快速、轻松地得到任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序java
Authentication:有时称为“登陆”,这是证实用户是他们所说的用户的行为。
Authorization:访问控制的过程,即肯定“谁”有权访问“什么”。
Session Manager:管理特定于用户的会话,即便在非web或EJB应用程序中也是如此。
Cryptography:使用密码算法保持数据安全,同时仍然易于使用。git
三个核心组件:Subject, SecurityManager 和 Realmsgithub
Subject:即“当前操做用户”。可是,在Shiro中,Subject这一律念并不单单指人,也能够是第三方进程、后台账户(Daemon Account)或其余相似事物。它仅仅意味着“当前跟软件交互的东西”。Subject表明了当前用户的安全操做,SecurityManager则管理全部用户的安全操做。
SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro经过SecurityManager来管理内部组件实例,并经过它来提供安全管理的各类服务。
Realm: Realm充当了Shiro与应用安全数据间的“桥梁”或者“链接器”。也就是说,当对用户执行认证(登陆)和受权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。web
简单介绍流程,首先须要导入的依赖算法
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.5.0</version> </dependency>
若是thymeleaf须要整合shiro的话导入以下依赖spring
<dependency> <groupId>com.github.theborakompanioni</groupId> <artifactId>thymeleaf-extras-shiro</artifactId> <version>2.0.0</version> </dependency>
自定义realmapache
package com.hzy.config; import com.hzy.pojo.User; import com.hzy.service.UserService; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.*; 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.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; // 自定义realm public class UserRealm extends AuthorizingRealm { @Autowired private UserService userService; // 认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { System.out.println("认证"); UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; User user = userService.queryUserByName(token.getUsername()); if (user == null) { return null; } Subject currentSubject = SecurityUtils.getSubject(); currentSubject.getSession().setAttribute("loginUser",user); // 密码认证shiro作 return new SimpleAuthenticationInfo(user,user.getPassword(),""); } // 受权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { System.out.println("受权"); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); // info.addStringPermission("user:add"); // 拿到当前用户的对象 Subject subject = SecurityUtils.getSubject(); User currentUser = (User) subject.getPrincipal(); //拿到user对象 // 设置当前用户的权限 info.addStringPermission(currentUser.getPerms()); return info; } }
ShiroConfig 安全
package com.hzy.config; import at.pollux.thymeleaf.shiro.dialect.ShiroDialect; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.LinkedHashMap; import java.util.Map; @Configuration public class ShiroConfig { //ShiroFilterFactoryBean @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean (@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager ) { ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); // 设置安全管理器 bean.setSecurityManager(defaultWebSecurityManager); // 添加shiro内置过滤器 /* * anno:无需认证就能够访问 * authc:必须认证才能访问 * user:必须拥有记住我功能才能访问 * perms:拥有某个资源的权限才能访问 * role:拥有某个角色的权限才能访问 * */ // 拦截 Map<String,String> filterMap = new LinkedHashMap<>(); // 受权 filterMap.put("/user/add","perms[user:add]"); filterMap.put("/user/update","perms[user:update]"); //filterMap.put("/user/*","authc"); bean.setFilterChainDefinitionMap(filterMap); // 设置登陆请求 bean.setLoginUrl("/toLogin"); // 未受权页面 bean.setUnauthorizedUrl("/noauth"); return bean; } //DefaultWebSecurityManager @Bean(name = "securityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); // 关联UserRealm securityManager.setRealm(userRealm); return securityManager; } //建立realm对象 @Bean public UserRealm userRealm() { return new UserRealm(); } // 整合ShiroDialect:用来整合shiro和thymeleaf @Bean public ShiroDialect getShiroDialect() { return new ShiroDialect(); } }
MyController 网络
package com.hzy.controller; import org.apache.catalina.security.SecurityUtil; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.IncorrectCredentialsException; import org.apache.shiro.authc.UnknownAccountException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class MyController { @RequestMapping({"/","/index"}) public String index(Model model) { model.addAttribute("msg","hello shiro"); return "index"; } @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"; } @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); return "index"; }catch (UnknownAccountException e) { model.addAttribute("msg", "用户名不存在"); return "login"; }catch (IncorrectCredentialsException e) { model.addAttribute("msg", "密码错误"); return "login"; } } @RequestMapping("/noauth") @ResponseBody public String unauthorized() { return "未受权没法访问此页面"; } }
效果演示,不一样的用户会看见不一样的界面app
首页是一个登陆的连接
登陆不一样的用户会看到不一样的界面