<form action="${pageContext.request.contextPath}/user/login" method="post"> Username:<input type="text" name="username"></br> Password:<input type="password" name="password"></br> <input type="submit" value="提交"> </form>
@Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(SecurityManager securityManager){ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); Map<String,String> map = new HashMap<>(); //多個過濾器 AnonymousFilter 匿名過濾器 anon // FormAuthenticationFilter 認證過濾器 authc map.put("/**","authc"); map.put("/user/*","anon"); shiroFilterFactoryBean.setFilterChainDefinitionMap(map); shiroFilterFactoryBean.setLoginUrl("/main/login.jsp"); return shiroFilterFactoryBean; } @Bean public SecurityManager getSecurityManager(Realm realm){ //web環境下securityManage的實現類爲DefaultWebSecurityManager SecurityManager securityManager = new DefaultWebSecurityManager(); ((DefaultWebSecurityManager) securityManager).setRealm(realm); return securityManager; }
再次發起請求,ok 但因爲認證未設置 因此沒有成功的跳轉。html
public class MyRealm extends AuthorizingRealm { @Autowired private UserMapper userMapper; @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { String principal =(String) authenticationToken.getPrincipal(); User user= new User(); user.setUsername(principal); User user1 = userMapper.selectOne(user); AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(principal,user1.getPassword(),ByteSource.Util.bytes("salt"),this.getName()); return authenticationInfo; } @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal(); System.out.println("================================"); User user= new User(); user.setUsername(primaryPrincipal); User user1 = userMapper.selectOne(user); if(primaryPrincipal.equals(user1.getUsername())){ SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); authorizationInfo.addRole("super"); authorizationInfo.addStringPermission("user:delete"); authorizationInfo.addStringPermissions(Arrays.asList("admin:delete","admin:add")); return authorizationInfo; } return null; } }
@Configuration public class ShiroFilterConf { @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(SecurityManager securityManager){ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); //shiro會對全部資源進行控制,默認不攔截 須要配置 Map<String,String> map = new HashMap<>(); //多個過濾器 AnonymousFilter 匿名過濾器 anon // FormAuthenticationFilter 認證過濾器 authc map.put("/**","authc"); map.put("/user/*","anon"); map.put("/index.jsp","anon"); //多個過濾器組成過濾器鏈 shiroFilterFactoryBean.setFilterChainDefinitionMap(map); //設置認證頁面路徑 shiroFilterFactoryBean.setLoginUrl("/main/login.jsp"); return shiroFilterFactoryBean; } @Bean public SecurityManager getSecurityManager(Realm realm,CacheManager cacheManager){ //web環境下securityManage的實現類爲DefaultWebSecurityManager SecurityManager securityManager = new DefaultWebSecurityManager(); ((DefaultWebSecurityManager) securityManager).setRealm(realm); ((DefaultWebSecurityManager) securityManager).setCacheManager(cacheManager); return securityManager; } @Bean public Realm getRealm(CredentialsMatcher credentialsMatcher){ MyRealm myRealm = new MyRealm(); myRealm.setCredentialsMatcher(credentialsMatcher); return myRealm; } @Bean public CredentialsMatcher getCredentialsMatcher(){ HashedCredentialsMatcher hm = new HashedCredentialsMatcher(); hm.setHashAlgorithmName("MD5"); hm.setHashIterations(1024); return hm; } @Bean public CacheManager getCacheManager(){ CacheManager cacheManager = new EhCacheManager(); return cacheManager; } }
<%@ page contentType="text/html;charset=UTF-8" isELIgnored="false" %> <%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %> <html> <head> <title>Title</title> </head> <body> <shiro:authenticated> hello:<shiro:principal></shiro:principal> <a href="${pageContext.request.contextPath}/user/logout">登出</a> <ul> <li>專輯</li> <li>章節</li> <li>用戶</li> <shiro:hasRole name="super"> <li>管理員</li> <shiro:hasPermission name="admin:delete"> 刪 </shiro:hasPermission> <shiro:hasPermission name="admin:add"> 增 </shiro:hasPermission> <shiro:hasPermission name="admin:update"> 改 </shiro:hasPermission> </shiro:hasRole> </ul> </shiro:authenticated> <shiro:notAuthenticated> <a href="${pageContext.request.contextPath}/main/login.jsp">你好請登陸</a> </shiro:notAuthenticated> </body> </html>
<shiro:principal></shiro:principal> //用戶的身份信息 <shiro:authenticated></shiro:authenticated> //認證成功 執行標籤體的內容 <shiro:notAuthenticated></shiro:notAuthenticated> //未認證 執行標籤體內容 //基於角色的權限管理 <shiro:hasRole name="super"></shiro:hasRole> <shiro:hasAnyRoles name="admin,super"></shiro:hasAnyRoles> //基於資源的權限管理 <shiro:hasPermission name="user:delete"></shiro:hasPermission>
若是沒有緩存,一個Permission或者role判斷要查詢三次數據庫-username查主體--主體查角色---角色查權限,這樣對於數據庫的壓力太大,須要設置緩存。並且要注意到,在第一次查詢時shiro就會多個Permission或者Role判斷設置一次緩存,就是說,受權方法doGetAuthorizationInfo只走一次。
shiro緩存是在內存中的。java
ehcache主包必須導入,shiro集成時CacheManager是沒有實現的,主包中才有實現類EhCacheManagerweb
@Bean public CacheManager getCacheManager(){ CacheManager cacheManager = new EhCacheManager(); return cacheManager; }