springboot+thymeleaf+shiro標簽的實例
更新時間:2022年01月25日 10:46:15 作者:占星安啦
這篇文章主要介紹了springboot+thymeleaf+shiro標簽的實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
1、pom中加入依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> <version>1.5.6.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf --> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf</artifactId> <version>${thymeleaf.version}</version> </dependency> <!-- shiro安全框架 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version> </dependency> <!--thymeleaf-shiro-extras--> <dependency> <groupId>com.github.theborakompanioni</groupId> <artifactId>thymeleaf-extras-shiro</artifactId> <version>1.2.1</version> </dependency>
2、用戶-角色-權(quán)限的表關(guān)系
//用戶表 public class User { private Integer userId; private String userName; private Set<Role> roles = new HashSet<>(); } //角色表 public class User { private Integer id; private String role; private Set<Module> modules = new HashSet<>(); private Set<User> users = new HashSet<>(); } //權(quán)限表 public class Module { private Integer mid; private String mname; private Set<Role> roles = new HashSet<>(); } //用戶查詢 <resultMap id="BaseResultMap" type="com.lanyu.common.model.User" > <id column="user_id" property="userId" jdbcType="INTEGER" /> <result column="user_name" property="userName" jdbcType="VARCHAR" /> <!-- 多對多關(guān)聯(lián)映射:collection --> <collection property="roles" ofType="Role"> <id property="id" column="c_id" /> <result property="role" column="role" /> <collection property="modules" ofType="Module"> <id property="mid" column="mid"/> <result property="mname" column="mname"/> </collection> </collection> </resultMap> //查詢用戶信息,返回結(jié)果會自動分組,得到用戶信息 <select id="selectByPhone" resultMap="BaseResultMap" parameterType="java.lang.String" > SELECT u.*, r.*, m.* FROM sys_user u INNER JOIN sys_user_role ur ON ur.userId = u.user_id INNER JOIN sys_role r ON r.rid = ur.roleid INNER JOIN sys_role_module mr ON mr.rid = r.rid INNER JOIN sys_module m ON mr.mid = m.mid WHERE u.user_name=#{username} or u.phone=#{username}; </select>
3、編寫shiro核心類
@Configuration public class ShiroConfiguration { //用于thymeleaf模板使用shiro標簽 @Bean public ShiroDialect shiroDialect() { return new ShiroDialect(); } @Bean(name="shiroFilter") public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager manager) { ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean(); bean.setSecurityManager(manager); //配置登錄的url和登錄成功的url bean.setLoginUrl("/loginpage"); bean.setSuccessUrl("/indexpage"); //配置訪問權(quán)限 LinkedHashMap<String, String> filterChainDefinitionMap=new LinkedHashMap<>(); // filterChainDefinitionMap.put("/loginpage*", "anon"); //表示可以匿名訪問 filterChainDefinitionMap.put("/admin/*", "authc");//表示需要認證才可以訪問 filterChainDefinitionMap.put("/logout*","anon"); filterChainDefinitionMap.put("/img/**","anon"); filterChainDefinitionMap.put("/js/**","anon"); filterChainDefinitionMap.put("/css/**","anon"); filterChainDefinitionMap.put("/fomts/**","anon"); filterChainDefinitionMap.put("/**", "anon"); bean.setFilterChainDefinitionMap(filterChainDefinitionMap); return bean; } //配置核心安全事務(wù)管理器 @Bean(name="securityManager") public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm) { System.err.println("--------------shiro已經(jīng)加載----------------"); DefaultWebSecurityManager manager=new DefaultWebSecurityManager(); manager.setRealm(authRealm); return manager; } //配置自定義的權(quán)限登錄器 @Bean(name="authRealm") public AuthRealm authRealm(@Qualifier("credentialsMatcher") CredentialsMatcher matcher) { AuthRealm authRealm=new AuthRealm(); authRealm.setCredentialsMatcher(matcher); return authRealm; } //配置自定義的密碼比較器 @Bean(name="credentialsMatcher") public CredentialsMatcher credentialsMatcher() { return new CredentialsMatcher(); } @Bean public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){ return new LifecycleBeanPostProcessor(); } @Bean public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){ DefaultAdvisorAutoProxyCreator creator=new DefaultAdvisorAutoProxyCreator(); creator.setProxyTargetClass(true); return creator; } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager manager) { AuthorizationAttributeSourceAdvisor advisor=new AuthorizationAttributeSourceAdvisor(); advisor.setSecurityManager(manager); return advisor; } } — - - -- - -- - -- - -- - - -- - - - -- public class AuthRealm extends AuthorizingRealm { @Autowired private UserService userService; //認證.登錄 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { UsernamePasswordToken utoken=(UsernamePasswordToken) token;//獲取用戶輸入的token String username = utoken.getUsername(); User user = userService.selectByPhone(username); return new SimpleAuthenticationInfo(user, user.getPassword(),this.getClass().getName());//放入shiro.調(diào)用CredentialsMatcher檢驗密碼 } //授權(quán) @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) { User user=(User) principal.fromRealm(this.getClass().getName()).iterator().next();//獲取session中的用戶 List<String> permissions=new ArrayList<>(); Set<Role> roles = user.getRoleList(); SimpleAuthorizationInfo info=new SimpleAuthorizationInfo(); List<String> listrole = new ArrayList<>(); if(roles.size()>0) { for(Role role : roles) { if(!listrole.contains(role.getRole())){ listrole.add(role.getRole()); } Set<Module> modules = role.getModules(); if(modules.size()>0) { for(Module module : modules) { permissions.add(module.getMname()); } } } } info.addRoles(listrole); //將角色放入shiro中. info.addStringPermissions(permissions); //將權(quán)限放入shiro中. return info; } } //自定義密碼比較器 public class CredentialsMatcher extends SimpleCredentialsMatcher { private Logger logger = Logger.getLogger(CredentialsMatcher.class); @Override public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { UsernamePasswordToken utoken=(UsernamePasswordToken) token; //所需加密的參數(shù) 即 用戶輸入的密碼 String source = String.valueOf(utoken.getPassword()); //[鹽] 一般為用戶名 或 隨機數(shù) String salt = utoken.getUsername(); //加密次數(shù) int hashIterations = 50; SimpleHash sh = new SimpleHash("md5", source, salt, hashIterations); String Strsh =sh.toHex(); //打印最終結(jié)果 logger.info("正確密碼為:"+Strsh); //獲得數(shù)據(jù)庫中的密碼 String dbPassword= (String) getCredentials(info); logger.info("數(shù)據(jù)庫密碼為:"+dbPassword); //進行密碼的比對 return this.equals(Strsh, dbPassword); } }
4、登錄控制器
@RequestMapping("/loginUser") public String loginUser(String username,String password,HttpSession session) { UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken(username,password); Subject subject = SecurityUtils.getSubject(); Map map=new HashMap(); try { subject.login(usernamePasswordToken); //完成登錄 User user=(User) subject.getPrincipal(); session.setAttribute("user", user); return "index"; } catch (IncorrectCredentialsException e) { map.put("msg", "密碼錯誤"); } catch (LockedAccountException e) { map.put("msg", "登錄失敗,該用戶已被凍結(jié)"); } catch (AuthenticationException e) { map.put("msg", "該用戶不存在"); } catch (Exception e) { return "login";//返回登錄頁面 } return map.toString(); }
5、thymeleaf頁面權(quán)限控制
<html lang="zh_CN" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"> //作為屬性控制 <button type="button" shiro:authenticated="true" class="btn btn-outline btn-default"> <i class="glyphicon glyphicon-plus" aria-hidden="true"></i> </button> //作為標簽 <shiro:hasRole name="admin"> <button type="button" class="btn btn-outline btn-default"> <i class="glyphicon glyphicon-heart" aria-hidden="true"></i> </button> </shiro:hasRole>
6、標簽說明
guest標簽 <shiro:guest> </shiro:guest> 用戶沒有身份驗證時顯示相應(yīng)信息,即游客訪問信息。 user標簽 <shiro:user> </shiro:user> 用戶已經(jīng)身份驗證/記住我登錄后顯示相應(yīng)的信息。 authenticated標簽 <shiro:authenticated> </shiro:authenticated> 用戶已經(jīng)身份驗證通過,即Subject.login登錄成功,不是記住我登錄的。 notAuthenticated標簽 <shiro:notAuthenticated> </shiro:notAuthenticated> 用戶已經(jīng)身份驗證通過,即沒有調(diào)用Subject.login進行登錄,包括記住我自動登錄的也屬于未進行身份驗證。 principal標簽 <shiro: principal/> <shiro:principal property="username"/> 相當于((User)Subject.getPrincipals()).getUsername()。 lacksPermission標簽 <shiro:lacksPermission name="org:create"> </shiro:lacksPermission> 如果當前Subject沒有權(quán)限將顯示body體內(nèi)容。 hasRole標簽 <shiro:hasRole name="admin"> </shiro:hasRole> 如果當前Subject有角色將顯示body體內(nèi)容。 hasAnyRoles標簽 <shiro:hasAnyRoles name="admin,user"> </shiro:hasAnyRoles> 如果當前Subject有任意一個角色(或的關(guān)系)將顯示body體內(nèi)容。 lacksRole標簽 <shiro:lacksRole name="abc"> </shiro:lacksRole> 如果當前Subject沒有角色將顯示body體內(nèi)容。 hasPermission標簽 <shiro:hasPermission name="user:create"> </shiro:hasPermission> 如果當前Subject有權(quán)限將顯示body體內(nèi)容
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
解決java.sql.SQLException:?validateConnection?false問題的方法匯總(最
這篇文章主要給大家介紹了關(guān)于解決java.sql.SQLException:?validateConnection?false問題的方法匯總,文中通過圖文介紹的非常詳細,需要的朋友可以參考下2023-03-03Java9新特性Java.util.Optional優(yōu)化與增強解析
這篇文章主要為大家介紹了Java9新特性Java.util.Optional優(yōu)化與增強使用說明解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步2022-03-03解決Java導(dǎo)入excel大量數(shù)據(jù)出現(xiàn)內(nèi)存溢出的問題
今天小編就為大家分享一篇解決Java導(dǎo)入excel大量數(shù)據(jù)出現(xiàn)內(nèi)存溢出的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-06-06SpringBoot使用Spring Test進行集成測試的流程步驟
Spring Test 是 Spring Framework 提供的一個測試框架,它可以幫助我們進行集成測試,在本文中,我們將介紹如何使用 Spring Test 進行集成測試,需要的朋友可以參考下2023-06-06簡單了解springboot中的配置文件相關(guān)知識
這篇文章主要介紹了簡單了解springboot中的配置文件相關(guān)知識,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-11-11MyBatis中傳入?yún)?shù)parameterType類型詳解
這篇文章主要給大家介紹了關(guān)于MyBatis中傳入?yún)?shù)parameterType類型的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2018-04-04