I. Introduction
In order to manage small yellow map of the main line and, in particular, arranged a backstage management system, rights management is the preferred course of Shiro.
Second, the table design
The following table needs at least a few, depending on the specific design of how their business may be:
sys_user: user table
sys_role: Role table
sys_menu: Menu Table
sys_user_role: corresponding to the user role
sys_role_menu: corresponding to the user menu
Third, integration
pom.xml introduced:
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-web-starter</artifactId> <version>1.4.2</version></dependency>
Defined UserRealm:
/** * 用户认证 */public class UserRealm extends AuthorizingRealm { @Autowired private SysUserService userService; /** * 获取授权 * @param principalCollection * @return */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { Long userId = ShiroUtils.getUserId(); List<String> rolesSet = userService.listUserRoles(userId); List<String> permsSet = userService.listUserPerms(userId); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.setRoles(new HashSet<>(rolesSet)); info.setStringPermissions(new HashSet<>(permsSet)); return info; } /** * 获取认证 * @param authenticationToken * @return * @throws AuthenticationException */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { String username = (String) authenticationToken.getPrincipal(); String password = new String((char[]) authenticationToken.getCredentials()); SysUser user = userService.getUser(username); if (user == null) { throw new UnknownAccountException("账户不存在"); } if(!password.equals(user.getPassword())) { throw new IncorrectCredentialsException("密码不正确"); } return new SimpleAuthenticationInfo(user, password, getName()); }}
Defined ShiroConfig:
/ ** * Shiro rights profile * / @ Configurationpublic class ShiroConfig { @Bean public UserRealm userRealm() { return new UserRealm(); } @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean (SecurityManager securityManager) {ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean (); // must be set SecuritManager shiroFilterFactoryBean.setSecurityManager (securityManager); // set the login page shiroFilterFactoryBean.setLoginUrl ( "/ login.shtml"); // login after a successful jump to the link, if there is ajax invalid shiroFilterFactoryBean.setSuccessUrl ( "/ index"); // unauthorized interface; shiroFilterFactoryBean.setUnauthorizedUrl ( "/ 403"); // interceptor Map <String, String> filterChainDefinitionMap = new LinkedHashMap <> (); // filter chain is defined, performed sequentially from top to bottom, generally / ** on the lower most // authc: url must all be accessed by only authenticated; anon: All are all url anonymous access / ** * static file * / filterChainDefinitionMap.put ( "/ css / **", "anon"); filterChainDefinitionMap.put ( "/ images / **", "anon"); filterChainDefinitionMap.put ( " / js / ** ","anon"); filterChainDefinitionMap.put("/file/**","anon"); /** * 登录注册 */ filterChainDefinitionMap.put("/register.shtml","anon"); filterChainDefinitionMap.put("/login.shtml","anon"); filterChainDefinitionMap.put("/sys/logout","anon"); filterChainDefinitionMap.put("/sys/login","anon"); filterChainDefinitionMap.put("/sys/register","anon"); /** * 管理后台 */ filterChainDefinitionMap.put("/sys/**", "roles[admin]"); filterChainDefinitionMap.put("/**", "authc"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; }/register.shtml","anon"); filterChainDefinitionMap.put("/login.shtml","anon"); filterChainDefinitionMap.put("/sys/logout","anon"); filterChainDefinitionMap.put("/sys/login","anon"); filterChainDefinitionMap.put("/sys/register","anon"); /** * 管理后台 */ filterChainDefinitionMap.put("/sys/**", "roles[admin]"); filterChainDefinitionMap.put("/**", "authc"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; }/register.shtml","anon"); filterChainDefinitionMap.put("/login.shtml","anon"); filterChainDefinitionMap.put("/sys/logout","anon"); filterChainDefinitionMap.put("/sys/login","anon"); filterChainDefinitionMap.put("/sys/register","anon"); /** * 管理后台 */ filterChainDefinitionMap.put("/sys/**", "roles[admin]"); filterChainDefinitionMap.put("/**", "authc"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } filterChainDefinitionMap.put("/sys/register","anon"); /** * 管理后台 */ filterChainDefinitionMap.put("/sys/**", "roles[admin]"); filterChainDefinitionMap.put("/**", "authc"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } filterChainDefinitionMap.put("/sys/register","anon"); /** * 管理后台 */ filterChainDefinitionMap.put("/sys/**", "roles[admin]"); filterChainDefinitionMap.put("/**", "authc"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } @Bean public SessionsSecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(userRealm()); securityManager.setSessionManager(sessionManager()); return securityManager; } @Bean public DefaultWebSessionManager sessionManager() { DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); //去掉小尾巴 JSESSIONID sessionManager.setSessionIdUrlRewritingEnabled(false); long time = 2*60*60*1000; sessionManager.setGlobalSessionTimeout(time); return sessionManager; }}
Login LoginController:
/** * 登录 */@Controller@RequestMapping("/sys")public class LoginController { private static final Logger logger = LoggerFactory.getLogger(LoginController.class); @Autowired private SysUserService sysUserService; /** * 登录 */ @PostMapping("/login") @ResponseBody public Result login(String username, String password){ logger.info("用户登录"); try{ Subject subject = ShiroUtils.getSubject(); password = MD5Utils.encrypt(username, password); UsernamePasswordToken token = new UsernamePasswordToken(username, password); subject.login(token); }catch (Exception e) { e.printStackTrace(); return Result.error("登录失败"); } return Result.ok("登录成功"); }}
Fourth, the filter
shiro and provide multiple default filters, we can use these filters to specify the url filter configuration access, here only a few of the more common.
Common access control annotations, the controller may be used in the class.
Fifth, use the tip
过滤器实现了后端的权限控制访问,那么如何在前端来使用注解实现按钮的显示呢?通常 thymeleaf 是 SpringBoot的标配模板了,这里我们使用第三方插件来实现。
pom.xml引入:
<dependency> <groupId>com.github.theborakompanioni</groupId> <artifactId>thymeleaf-extras-shiro</artifactId> <version>2.0.0</version></dependency>
ShiroConfig 追加以下代码:
@Beanpublic ShiroDialect shiroDialect(){ return new ShiroDialect();}
页面头部引入:
<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
页面使用:
<!-- 显示登陆用户昵称 --><shiro:principal property="nickname"/> <!-- 游客 --><p shiro:guest="">Please <a href="login.html">login</a></p> <!-- 认证通过或已记住的用户。--><p shiro:user="">Welcome back John! Not John? Click <a href="login.html">here</a> to login.</p> <!-- 已认证通过的用户。不包含已记住的用户,这是与user标签的区别所在。--><p shiro:authenticated="">Hello, <span shiro:principal=""></span>, how are you today?</p> <a shiro:authenticated="" href="updateAccount.html">Update your contact information</a> <!-- 输出当前用户信息,通常为登录帐号信息。--><p>Hello, <shiro:principal/>, how are you today?</p> <!-- 未认证通过用户,与authenticated标签相对应。与guest标签的区别是,该标签包含已记住用户。--><p shiro:notAuthenticated="">Please <a href="login.html">login</a> in order to update your credit card information.</p> <!-- 验证当前用户是否属于该角色。--><a shiro:hasRole="admin" href="admin.html">Administer the system</a><!-- 拥有该角色 --> <!-- 与hasRole标签逻辑相反,当用户不属于该角色时验证通过。--><p shiro:lacksRole="developer"><!-- 没有该角色 -->Sorry, you are not allowed to developer the system.</p> <!-- 验证当前用户是否属于以下所有角色。--><p shiro:hasAllRoles="developer, 2"><!-- 角色与判断 -->You are a developer and a admin.</p> <!-- 验证当前用户是否属于以下任意一个角色。--><p shiro:hasAnyRoles="admin, vip, developer,1"><!-- 角色或判断 -->You are a admin, vip, or developer.</p> <!--验证当前用户是否拥有指定权限。--><a shiro:hasPermission="userInfo:add" href="createUser.html">添加用户</a><!-- 拥有权限 --> <!-- 与hasPermission标签逻辑相反,当前用户没有制定权限时,验证通过。--><p shiro:lacksPermission="userInfo:del"><!-- 没有权限 -->Sorry, you are not allowed to delete user accounts.</p> <! - Verify that the current user has all of the following roles. -> <p shiro: hasAllPermissions = ! "userInfo: view, userInfo: add"> <- authority and judgment -> by You CAN See the Users or the Add </ the p->. <- Verify that the current user has the following! arbitrary authority. -> <p shiro: hasAnyPermissions = ! "userInfo: view, userInfo: del"> <- or permission determination -> You can see or delete users </ p> <a shiro: hasPermission = "pp" href. = "createUser.html"> Create a new User </a>
VI Summary
Huang finally have the background of the chart! ! !