版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014155085/article/details/79174447
github地址:https://github.com/theborakompanioni/thymeleaf-extras-shiro
ps:此文章需要相应的shiro基础,内容很精简
1.pom.xml
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <thymeleaf.version>3.0.3.RELEASE</thymeleaf.version> <thymeleaf-layout-dialect.version>2.2.1</thymeleaf-layout-dialect.version> </properties>
<!--shiro相关--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.5</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.2.5</version> </dependency> <!--加入thymeleaf--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>nz.net.ultraq.thymeleaf</groupId> <artifactId>thymeleaf-layout-dialect</artifactId> </dependency> <!--thymeleaf使用shiro--> <dependency> <groupId>com.github.theborakompanioni</groupId> <artifactId>thymeleaf-extras-shiro</artifactId> <version>2.0.0</version> </dependency>2.shiro 相关配置
2.1
package com.example.competition.shiro; import at.pollux.thymeleaf.shiro.dialect.ShiroDialect; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.spring.LifecycleBeanPostProcessor; import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.filter.authc.LogoutFilter; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn; import javax.servlet.Filter; import java.util.LinkedHashMap; import java.util.Map; /** * shiro配置类 * Created by cdyoue on 2016/10/21. */ @Configuration public class ShiroConfiguration { /** * LifecycleBeanPostProcessor,这是个DestructionAwareBeanPostProcessor的子类, * 负责org.apache.shiro.util.Initializable类型bean的生命周期的,初始化和销毁。 * 主要是AuthorizingRealm类的子类,以及EhCacheManager类。 */ @Bean(name = "lifecycleBeanPostProcessor") public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } /** * HashedCredentialsMatcher,这个类是为了对密码进行编码的, * 防止密码在数据库里明码保存,当然在登陆认证的时候, * 这个类也负责对form里输入的密码进行编码。 */ @Bean(name = "hashedCredentialsMatcher") public HashedCredentialsMatcher hashedCredentialsMatcher() { HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher(); credentialsMatcher.setHashAlgorithmName("MD5"); credentialsMatcher.setHashIterations(2); credentialsMatcher.setStoredCredentialsHexEncoded(true); return credentialsMatcher; } /** * ShiroRealm, ,继承自AuthorizingRealm, * 负责用户的认证和权限的处理,可以参考JdbcRealm的实现。 */ @Bean(name = "shiroRealm") @DependsOn("lifecycleBeanPostProcessor") public ShiroRealm shiroRealm() { ShiroRealm realm = new ShiroRealm(); // realm.setCredentialsMatcher(hashedCredentialsMatcher()); return realm; } // /** // * EhCacheManager,缓存管理,用户登陆成功后,把用户信息和权限信息缓存起来, // * 然后每次用户请求时,放入用户的session中,如果不设置这个bean,每个请求都会查询一次数据库。 // */ // @Bean(name = "ehCacheManager") // @DependsOn("lifecycleBeanPostProcessor") // public EhCacheManager ehCacheManager() { // return new EhCacheManager(); // } /** * SecurityManager,权限管理,这个类组合了登陆,登出,权限,session的处理,是个比较重要的类。 * // */ @Bean(name = "securityManager") public DefaultWebSecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(shiroRealm()); // securityManager.setCacheManager(ehCacheManager()); return securityManager; } /** * ShiroFilterFactoryBean,是个factorybean,为了生成ShiroFilter。 * 它主要保持了三项数据,securityManager,filters,filterChainDefinitionManager。 */ @Bean(name = "shiroFilter") public ShiroFilterFactoryBean shiroFilterFactoryBean() { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager()); Map<String, Filter> filters = new LinkedHashMap<String, Filter>(); LogoutFilter logoutFilter = new LogoutFilter(); logoutFilter.setRedirectUrl("/login"); // filters.put("logout",null); shiroFilterFactoryBean.setFilters(filters); Map<String, String> filterChainDefinitionManager = new LinkedHashMap<String, String>(); filterChainDefinitionManager.put("/logout", "logout"); filterChainDefinitionManager.put("/user/**", "authc,roles[ROLE_USER]"); filterChainDefinitionManager.put("/events/**", "authc,roles[ROLE_ADMIN]"); // filterChainDefinitionManager.put("/user/edit/**", "authc,perms[user:edit]");// 这里为了测试,固定写死的值,也可以从数据库或其他配置中读取 filterChainDefinitionManager.put("/**", "anon"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionManager); shiroFilterFactoryBean.setSuccessUrl("/"); shiroFilterFactoryBean.setUnauthorizedUrl("/403"); return shiroFilterFactoryBean; } /** * DefaultAdvisorAutoProxyCreator,Spring的一个bean,由Advisor决定对哪些类的方法进行AOP代理。 */ @Bean @ConditionalOnMissingBean public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator(); defaultAAP.setProxyTargetClass(true); return defaultAAP; } /** * AuthorizationAttributeSourceAdvisor,shiro里实现的Advisor类, * 内部使用AopAllianceAnnotationsAuthorizingMethodInterceptor来拦截用以下注解的方法。 */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() { AuthorizationAttributeSourceAdvisor aASA = new AuthorizationAttributeSourceAdvisor(); aASA.setSecurityManager(securityManager()); return aASA; } @Bean public ShiroDialect shiroDialect() { return new ShiroDialect(); } }2.2此类根据自己数据库修改
扫描二维码关注公众号,回复:
3970207 查看本文章
package com.example.competition.shiro; import com.example.competition.dao.dto.UserRoleDTO; import com.example.competition.dao.mapper.PermissionMapper; import com.example.competition.dao.mapper.UserMapper; import com.example.competition.dao.model.Permission; import com.example.competition.dao.model.Role; import lombok.extern.slf4j.Slf4j; 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.springframework.beans.factory.annotation.Autowired; import java.util.HashMap; import java.util.Map; /** * Created by cdyoue on 2016/10/21. */ @Slf4j public class ShiroRealm extends AuthorizingRealm { @Autowired private UserMapper userMapper; @Autowired private PermissionMapper permissionMapper; /** 授权访问控制 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { log.info("doGetAuthorizationInfo:"+principalCollection.toString()); Map<String,Object> map=new HashMap<>(); map.put("username",principalCollection.getPrimaryPrincipal()); UserRoleDTO userRoleDTO = userMapper.selectUserAndRole(map); //把principals放session中 key=userId value=principals SecurityUtils.getSubject().getSession().setAttribute(String.valueOf(userRoleDTO.getUserId()),SecurityUtils.getSubject().getPrincipals()); SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); //赋予角色 for(Role userRole:userRoleDTO.getRoles()){ simpleAuthorizationInfo.addRole(userRole.getRoleName()); } //赋予权限 for(Permission permission:permissionMapper.selectPermissionByUserId(userRoleDTO.getUserId())){ // if(StringUtils.isNotBlank(permission.getPermCode())) simpleAuthorizationInfo.addStringPermission(permission.getpName()); } //设置登录次数、时间 // userService.updateUserLogin(user); return simpleAuthorizationInfo; } /** 验证用户身份 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { log.info("doGetAuthenticationInfo:" + authenticationToken.toString()); UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; String userName=token.getUsername(); log.info(userName+token.getPassword()); Map<String,Object> map=new HashMap<>(); map.put("username",token.getUsername()); UserRoleDTO userRoleDTO = userMapper.selectUserAndRole(map); if (userRoleDTO != null) { // byte[] salt = Encodes.decodeHex(user.getSalt()); // ShiroUser shiroUser=new ShiroUser(user.getId(), user.getLoginName(), user.getName()); //设置用户session SecurityUtils.getSubject().getSession().setAttribute("user", userRoleDTO); return new SimpleAuthenticationInfo(userName,userRoleDTO.getPassword(),getName()); } else { return null; } // return null; } }3.页面
<!DOCTYPE html> <html xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"> <head> <title>thymeleaf-extras-shiro</title> </head> <body> <p shiro:guest="">Please <a href="login.html">login</a></p> <p shiro:authenticated=""> Hello, <span shiro:principal=""></span>, how are you today? </p> </body> </html>