springboot shiro認證受權

shiro必備表:用戶,角色,權限     1:1:n   其中一種(可變)css

------------------------------------------------------------------html

shiro配置(相似於ssm中的xml配置)java

package cn.xydata.config.shiro;

import cn.xydata.entity.system.Permission;
import cn.xydata.service.impl.system.PermisssionServiceImpl;
import cn.xydata.service.system.PermissionService;
import org.apache.shiro.cache.ehcache.EhCacheManager;
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.mgt.DefaultWebSecurityManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Configuration
public class ShiroConfig {
private static final Logger logger = LoggerFactory.getLogger(ShiroConfig.class);

@Bean(name="permissionService")
public PermissionService getPermissionService(){
return new PermisssionServiceImpl();
}


@Bean(name = "shiroEhcacheManager")
public EhCacheManager getEhCacheManager() {
EhCacheManager em = new EhCacheManager();
em.setCacheManagerConfigFile("classpath:ehcache.xml");
return em;
}

@Bean(name = "myShiroRealm")
public MyShiroRealm getShiroRealm() {
MyShiroRealm realm = new MyShiroRealm();
realm.setCacheManager(getEhCacheManager());
return realm;
}
@Bean(name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}

@Bean
public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
daap.setProxyTargetClass(true);
return daap;
}

@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager() {
DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager();
dwsm.setRealm(getShiroRealm());
dwsm.setCacheManager(getEhCacheManager());

return dwsm;
}

@Bean
public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor() {
AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
aasa.setSecurityManager(getDefaultWebSecurityManager());
return aasa;
}

private void loadShiroFilterChain(ShiroFilterFactoryBean shiroFilterFactoryBean){
//關聯數據庫權限
List<Permission> Permissions=getPermissionService().getPermissions();

logger.info(String.valueOf(Permissions.size()));
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
for (Permission permission : Permissions) {
filterChainDefinitionMap.put(permission.getPageUrl(),"authc,perms["+permission.getId()+"]");
}
//放行靜態資源和登錄界面
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/css/**", "anon");
filterChainDefinitionMap.put("/js/**", "anon");
filterChainDefinitionMap.put("/bootstrap/**", "anon");
filterChainDefinitionMap.put("/img/**", "anon");
filterChainDefinitionMap.put("/dist/**", "anon");
filterChainDefinitionMap.put("/plugins/**", "anon");
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
}
//shiro攔截
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean getShiroFilterFactoryBean() {
ShiroFilterFactoryBean shiroFilterFactoryBean=null;
try {
shiroFilterFactoryBean = new MyShiroFilterFactoryBean();

shiroFilterFactoryBean.setSecurityManager(getDefaultWebSecurityManager());

shiroFilterFactoryBean.setLoginUrl("/login");

shiroFilterFactoryBean.setSuccessUrl("/index.html");
shiroFilterFactoryBean.setUnauthorizedUrl("/403");

loadShiroFilterChain(shiroFilterFactoryBean);

} catch (Exception e) {

e.printStackTrace();
}
return shiroFilterFactoryBean;
}

}
-----------------------------------------------------------------------------------------------------------
自定義ShiroRealm,實現對自定義數據表的操做
package cn.xydata.config.shiro;

import cn.xydata.entity.system.User;
import cn.xydata.mapper.system.UserMapper;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.PostConstruct;
import java.util.Set;


public class MyShiroRealm extends AuthorizingRealm {

private static final Logger logger = LoggerFactory.getLogger(MyShiroRealm.class);
private static final String ALGORITHM = "MD5";

@Autowired
private UserMapper userMapper;

@PostConstruct
public void initCredentialsMatcher() {
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(ALGORITHM);
setCredentialsMatcher(matcher);
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
logger.info("##################執行Shiro受權##################");
String username= (String)super.getAvailablePrincipal(principalCollection);
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
Set<String> roles = userMapper.findUserRoles(username);
authorizationInfo.setRoles(roles);
Set<String> permissions = userMapper.findUserPermissions(username);
authorizationInfo.setStringPermissions(permissions);

return authorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authenticationToken) throws AuthenticationException {
//認證
UsernamePasswordToken token=(UsernamePasswordToken) authenticationToken;
logger.info("驗證當前Subject時獲取到token爲:" + ReflectionToStringBuilder.toString(token, ToStringStyle.MULTI_LINE_STYLE));
String username = (String) token.getPrincipal();
User user=userMapper.findByUsername(username);
if (user==null) {
throw new UnknownAccountException();//沒找到賬號
}
Subject currentUser = SecurityUtils.getSubject();
currentUser.getSession().setAttribute("userid", user.getId());
currentUser.getSession().setAttribute("isadmin", user.getAdmin());
currentUser.getSession().setAttribute("username", username);

if (Boolean.TRUE.equals(user.getLocked())) {
throw new LockedAccountException(); //賬號鎖定
}
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
user.getUsercode(),
user.getPasswd(),
getName()
);
/* SimpleByteSource sbs=new SimpleByteSource(user.getUsercode().getBytes());
authenticationInfo.setCredentialsSalt(sbs);*/
return authenticationInfo;
}

}

-----------------------------------------------------------------------------------------------------------
//自定義攔截工廠
package cn.xydata.config.shiro;

import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.mgt.FilterChainManager;
import org.apache.shiro.web.filter.mgt.FilterChainResolver;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.mgt.WebSecurityManager;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.beans.factory.BeanInitializationException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

public class MyShiroFilterFactoryBean extends ShiroFilterFactoryBean {

private Set<String> ignoreExt;

public MyShiroFilterFactoryBean() {
super();
ignoreExt = new HashSet<>();
ignoreExt.add(".jpg");
ignoreExt.add(".png");
ignoreExt.add(".gif");
ignoreExt.add(".bmp");
ignoreExt.add(".js");
ignoreExt.add(".css");
}

@Override
protected AbstractShiroFilter createInstance() throws Exception {

SecurityManager securityManager = getSecurityManager();
if (securityManager == null) {
String msg = "SecurityManager property must be set.";
throw new BeanInitializationException(msg);
}

if (!(securityManager instanceof WebSecurityManager)) {
String msg = "The security manager does not implement the WebSecurityManager interface.";
throw new BeanInitializationException(msg);
}

FilterChainManager manager = createFilterChainManager();

PathMatchingFilterChainResolver chainResolver = new PathMatchingFilterChainResolver();
chainResolver.setFilterChainManager(manager);

return new MSpringShiroFilter((WebSecurityManager) securityManager, chainResolver);
}

private final class MSpringShiroFilter extends AbstractShiroFilter {

protected MSpringShiroFilter(WebSecurityManager webSecurityManager, FilterChainResolver resolver) {
super();
if (webSecurityManager == null) {
throw new IllegalArgumentException("WebSecurityManager property cannot be null.");
}
setSecurityManager(webSecurityManager);
if (resolver != null) {
setFilterChainResolver(resolver);
}
}

@Override
protected void doFilterInternal(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest)servletRequest;
String str = request.getRequestURI().toLowerCase();
boolean flag = true;
int idx = 0;
if(( idx = str.indexOf(".")) > 0){
str = str.substring(idx);
if(ignoreExt.contains(str.toLowerCase()))
flag = false;
}
if(flag){
super.doFilterInternal(servletRequest, servletResponse, chain);
}else{
chain.doFilter(servletRequest, servletResponse);
}
}

}
}
-----------------------------------------------------------------------------------------
shiro的實例應用
@ResponseBody()@RequestMapping(value = "/login",method = RequestMethod.POST)public Response login(        @RequestParam(value="userName",required=false,defaultValue="") String userName,        @RequestParam(value="passWord",required=false,defaultValue="") String passWord,        @RequestParam(value="rememberMe",required=false,defaultValue="false") boolean rememberMe,        RedirectAttributes redirectAttributes) {    UsernamePasswordToken token = new UsernamePasswordToken(userName, passWord,rememberMe);    Subject currentUser = SecurityUtils.getSubject();    try {        logger.info("對用戶[" + userName + "]進行登陸驗證..驗證開始");        currentUser.login(token);        logger.info("對用戶[" + userName + "]進行登陸驗證..驗證經過");    }catch(UnknownAccountException uae){        logger.info("對用戶[" + userName + "]進行登陸驗證..驗證未經過,未知帳戶");        redirectAttributes.addFlashAttribute("message", "用戶名不存在");        return new Response(ExceptionMsg.LoginNameNotExists);    }catch(IncorrectCredentialsException ice){        logger.info("對用戶[" + userName + "]進行登陸驗證..驗證未經過,錯誤的憑證");        redirectAttributes.addFlashAttribute("message", "密碼不正確");        return new Response(ExceptionMsg.PassWordError);    }catch(LockedAccountException lae){        logger.info("對用戶[" + userName + "]進行登陸驗證..驗證未經過,帳戶已鎖定");        redirectAttributes.addFlashAttribute("message", "帳戶已鎖定");        return new Response(ExceptionMsg.UserLock);    }catch(ExcessiveAttemptsException eae){        logger.info("對用戶[" + userName + "]進行登陸驗證..驗證未經過,錯誤次數過多");        redirectAttributes.addFlashAttribute("message", "用戶名或密碼錯誤次數過多");        return new Response(ExceptionMsg.LoginNameOrPassWordError);    }catch(AuthenticationException ae){        logger.info("對用戶[" + userName + "]進行登陸驗證..驗證未經過,堆棧軌跡以下");        ae.printStackTrace();        redirectAttributes.addFlashAttribute("message", "用戶名或密碼不正確");        return new Response(ExceptionMsg.LoginNameOrPassWordError);    }    if(currentUser.isAuthenticated()){        httpSession.setAttribute("username", currentUser.getPrincipal());        return new Response(ExceptionMsg.SUCCESS);    }else{        return new Response(ExceptionMsg.FAILED);    }}
相關文章
相關標籤/搜索